package com.dhcc.bpm.modules.metadata.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.dhcc.bpm.common.annotation.Log;
import com.dhcc.bpm.common.config.TemplateConfig;
import com.dhcc.bpm.common.constant.FilePathConstant;
import com.dhcc.bpm.common.enums.BusinessType;
import com.dhcc.bpm.common.utils.*;
import com.dhcc.bpm.modules.api.entity.BaseProduct;
import com.dhcc.bpm.modules.api.entity.Product;
import com.dhcc.bpm.modules.api.entity.ProductApi;
import com.dhcc.bpm.modules.api.service.IApiService;
import com.dhcc.bpm.modules.api.service.IBaseProductService;
import com.dhcc.bpm.modules.api.service.IProductApiService;
import com.dhcc.bpm.modules.api.service.IProductService;
import com.dhcc.bpm.modules.api.vo.ApiVO;
import com.dhcc.bpm.modules.common.entity.Plupload;
import com.dhcc.bpm.modules.common.entity.Upload;
import com.dhcc.bpm.modules.common.service.IPluploadService;
import com.dhcc.bpm.modules.content.entity.Sdk;
import com.dhcc.bpm.modules.content.service.ISdkService;
import com.dhcc.bpm.modules.gateway.entity.Gateway;
import com.dhcc.bpm.modules.gateway.service.IGatewayService;
import com.dhcc.bpm.modules.metadata.entity.*;
import com.dhcc.bpm.modules.metadata.service.*;
import com.dhcc.bpm.modules.metadata.vo.ApiMetadataVO;
import com.dhcc.bpm.modules.metadata.vo.MetadataVO;
import com.dhcc.bpm.modules.metadata.wrapper.ApiMetadataWrapper;
import com.dhcc.bpm.modules.orga.entity.AppApi;
import com.dhcc.bpm.modules.orga.service.IAppApiService;
import com.dhcc.bpm.modules.system.entity.Param;
import com.dhcc.bpm.modules.system.service.IDictService;
import com.dhcc.bpm.modules.system.service.ISerialNumberService;
import com.dhcc.bpm.modules.system.service.impl.ParamServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.entity.ContentType;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.log.annotation.ApiLog;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.scheduling.annotation.Async;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.*;
import java.net.MalformedURLException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 接口定义数据表 控制器
 *
 * @author ccab
 * @since 2020-06-03
 */
@RestController
@AllArgsConstructor
@NoArgsConstructor
@Slf4j
@RequestMapping("bpm-metadata/apimetadata")
@Api(value = "接口定义数据表", tags = "接口定义数据表接口")
public class ApiMetadataController extends BladeController {
    @Autowired
    private IApiMetadataService apiMetadataService;
    @Autowired
    private IAppApiService appApiService;
    @Autowired
    private IServerApiMetadataService serverApiMetadataService;
    @Autowired
    private IApiMetadataMapperService apiMetadataMapperService;
    @Autowired
    private IPluploadService pluploadService;
    @Autowired
    private IMetadataService metadataService;
    @Autowired
    private IApiService apiService;
    @Autowired
    private IProductService productService;
    @Autowired
    private IProductApiService productApiService;
    @Autowired
    private IDictService dictService;
    @Autowired
    private IGatewayService gatewayService;
    @Autowired
    private IBaseProductService baseProductService;
    @Autowired
    private IProdCodeService prodCodeService;
    @Autowired
    private ParamServiceImpl paramService;
    @Autowired
    private OpenapiGeneratorUtils openapiGeneratorUtils;
    @Autowired
    private com.dhcc.bpm.modules.metadata.mapper.StrucMetaMapper strucMetaMapper;
    @Autowired
    private ISerialNumberService serialNumberService;
    @Autowired
    private ISdkService sdkService;
    @Autowired
    private MavenInvokerUtils mavenInvokerUtils;

    @Value("${bpm.is-mvn-enable}")
    private boolean isEnable;

    private String path;
    private String prodCodePath;

    @Value("${bpm.file-public-path}")
    public void setFileUploadPath(String publicPath) {
        path = publicPath + FilePathConstant.OPENAPIPATH;
        prodCodePath = publicPath + FilePathConstant.PRODCODEPATH;
    }

    @Value("${bpm.privateKeyvalue}")
    private String privateKeyValueSet;
    @Value("${bpm.is-native}")
    private String isNative;
    @Value("${bpm.file-type}")
    private String supportFileType;
    /**
     * 详情
     */
    @GetMapping("/detail")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "详情", notes = "传入apiMetadata")
    public R<ApiMetadata> detail(ApiMetadata apiMetadata) {
        ApiMetadata detail = apiMetadataService.getOne(Condition.getQueryWrapper(apiMetadata));
        return R.data(detail);
    }

    /**
     * 分页 接口定义数据表
     */
    @GetMapping("/list")
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "分页", notes = "传入apiMetadata")
    public R<List<ApiMetadataVO>> list(ApiMetadataVO apiMetadata, Query query) {
        IPage<ApiMetadata> pages = apiMetadataService.page(Condition.getPage(query), Condition.getQueryWrapper(apiMetadata));
        List<ApiMetadataVO> list = new ArrayList<>();
        pages.getRecords().forEach(apiMetadata1 -> {
            ApiMetadataVO apiMetadataVO = new ApiMetadataVO();
            BeanUtils.copyProperties(apiMetadata1, apiMetadataVO);
            apiMetadataVO.setParentId(apiMetadata1.getGroupId() == null ? 0L : apiMetadata1.getGroupId());
            list.add(apiMetadataVO);
        });
        return R.data(ApiMetadataWrapper.build().listNodeVOs(list));
    }

    /**
     * 分页 接口定义数据表---请求参数
     */
    @GetMapping("/listReq")
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "分页", notes = "传入apiMetadata")
    public R<List<ApiMetadataVO>> listReq(ApiMetadataVO apiMetadata) {
        //----------------返回对象定义-------------
        List<ApiMetadataVO> sysReqHead = new ArrayList<>();
        List<ApiMetadataVO> sysResHead = new ArrayList<>();
        List<ApiMetadataVO> busReqHead = new ArrayList<>();
        List<ApiMetadataVO> busResHead = new ArrayList<>();
        List<ApiMetadataVO> reqBody = new ArrayList<>();
        List<ApiMetadataVO> resBody = new ArrayList<>();
        List<ApiMetadataVO> urlBody = new ArrayList<>();
        List<ApiMetadataVO> comReqBody = new ArrayList<>();
        List<ApiMetadataVO> comResBody = new ArrayList<>();

        List<String> reqIdsList = new ArrayList<>();//选中的请求元素id集合
        List<String> resIdsList = new ArrayList<>();//选中的响应元素id集合
        int isOrderEle = 0;
        Long sysId = 0L;
        Long gatewayId = 0L;
        boolean isGatewayQuery = false;
        if (apiMetadata.getGatewayId() != null && apiMetadata.getBaseProductId() == null) {
            isGatewayQuery = true;
        }
        if (apiMetadata.getSysId() != null) {
            sysId = apiMetadata.getSysId();
        } else if (apiMetadata.getBaseProductId() != null) {
            gatewayId = apiMetadata.getGatewayId();
//1.api发布来查询，通过基础产品可以查到系统id-----先查不是公共参数的
            BaseProduct baseProduct = baseProductService.getById(apiMetadata.getBaseProductId());
            apiMetadata.setSysId(baseProduct.getOpcSysId());
            sysId = baseProduct.getOpcSysId();
        } else if (apiMetadata.getApiId() != null) {
            //api发布的报文映射配置查询时传入apiId
            sysId = apiMetadataService.findSysIdByApiId(apiMetadata.getApiId()) == null ? 0L : apiMetadataService.findSysIdByApiId(apiMetadata.getApiId());
        }
        if (apiMetadata.getApiId() != null) {
            ApiMetadataVO apiV = new ApiMetadataVO();
            apiV.setApiComData("req" + apiMetadata.getApiId());
            comReqBody = apiMetadataService.selectApiMetadataList(apiV);
            apiV.setApiComData("res" + apiMetadata.getApiId());
            comResBody = apiMetadataService.selectApiMetadataList(apiV);
        }

        ApiMetadataVO apiMetadataVo = new ApiMetadataVO();
        //网关管理查询
        if (apiMetadata.getGatewayId() != null && sysId == 0L) {
            apiMetadataVo.setGatewayId(apiMetadata.getGatewayId());
        } else {
            apiMetadataVo.setSysId(sysId);
        }
        //查出所有的系统下节点这些基本都是一层节点含sysHead等
        List<ApiMetadataVO> sysTotalList = apiMetadataService.selectApiMetadataList(apiMetadataVo);

        /*订阅元素功能：门户端选中的，管理端只回显
        OrderEle 1:查看 即回显
        2：回显的同时可添加，必填元素不可选，非必填可以选择，并更新到opc_app_api表中*/
        if ("1".equals(apiMetadata.getOrderEle()) || "2".equals(apiMetadata.getOrderEle())) {
            isOrderEle = Integer.valueOf(apiMetadata.getOrderEle());
            AppApi appApi = new AppApi();
            appApi.setOpcAppId("".equals(apiMetadata.getAppId()) ? 0L : Long.valueOf(apiMetadata.getAppId()));
            appApi.setOpcApiId(apiMetadata.getApiId());
            List<AppApi> appApiList = appApiService.selectAppApiList(appApi);
            //opc_app_api表中取出要回显的数据
            if (appApiList.size() == 1) {
                if (appApiList.get(0).getRequestMessage() != null) {
                    String[] reqArr = appApiList.get(0).getRequestMessage().split(",");
                    reqIdsList = Arrays.asList(reqArr);
                }
                if (appApiList.get(0).getResponseMessage() != null) {
                    String[] resArr = appApiList.get(0).getResponseMessage().split(",");
                    resIdsList = Arrays.asList(resArr);
                }
            }
        }

        int finalIsOrderEle = isOrderEle;
        List<String> finalReqIdsList = reqIdsList;
        List<String> finalResIdsList = resIdsList;
        boolean finalGatewayQuery = isGatewayQuery;
        sysTotalList.forEach(apiMetadata1 -> {
            ApiMetadataVO apiMetadataVO = new ApiMetadataVO();
            BeanUtils.copyProperties(apiMetadata1, apiMetadataVO);
            apiMetadataVO.setParentId(apiMetadata1.getGroupId() == null ? 0L : apiMetadata1.getGroupId());

            if ("sysHead".equals(apiMetadataVO.getName()) && 1 == apiMetadataVO.getBodyType()) {
                //sysReqHead
                sysReqHead.add(apiMetadataVO);
                getChild(sysTotalList, apiMetadataVO.getId(), sysReqHead, finalIsOrderEle, finalReqIdsList);

            } else if ("sysHead".equals(apiMetadataVO.getName()) && 2 == apiMetadataVO.getBodyType()) {
                //sysResHead
                sysResHead.add(apiMetadataVO);
                getChild(sysTotalList, apiMetadataVO.getId(), sysResHead, finalIsOrderEle, finalResIdsList);
            } else if ("busHead".equals(apiMetadataVO.getName()) && 1 == apiMetadataVO.getBodyType()) {
                //busReqHead
                busReqHead.add(apiMetadataVO);
                List<ApiMetadataVO> list = new ArrayList<>();
                getChild(sysTotalList, apiMetadataVO.getId(), list, finalIsOrderEle, finalReqIdsList);
                List<ApiMetadataVO> tempList = list.stream()
                        .filter((ApiMetadataVO log) -> log.getBaseProductId() != null && log.getBaseProductId().equals(apiMetadata.getBaseProductId()))
                        .collect(Collectors.toList());
                busReqHead.addAll(tempList);
            } else if ("busHead".equals(apiMetadataVO.getName()) && 2 == apiMetadataVO.getBodyType()) {
                //busResHead
                busResHead.add(apiMetadataVO);
                List<ApiMetadataVO> list = new ArrayList<>();
                getChild(sysTotalList, apiMetadataVO.getId(), list, finalIsOrderEle, finalResIdsList);
                List<ApiMetadataVO> tempList = list.stream()
                        .filter((ApiMetadataVO log) -> log.getBaseProductId() != null && log.getBaseProductId().equals(apiMetadata.getBaseProductId()))
                        .collect(Collectors.toList());
                busResHead.addAll(tempList);
            } else if ("body".equals(apiMetadataVO.getName()) && 1 == apiMetadataVO.getBodyType()) {
                //reqBody
                reqBody.add(apiMetadataVO);
                List<ApiMetadataVO> list = new ArrayList<>();
                getChild(sysTotalList, apiMetadataVO.getId(), list, finalIsOrderEle, finalReqIdsList);
                List<ApiMetadataVO> tempList = list.stream()
                        .filter((ApiMetadataVO log) -> log.getApiId() != null && log.getApiId().equals(apiMetadata.getApiId()))
                        .collect(Collectors.toList());
                reqBody.addAll(tempList);

            } else if ("body".equals(apiMetadataVO.getName()) && 2 == apiMetadataVO.getBodyType()) {
                //resBody
                resBody.add(apiMetadataVO);
                List<ApiMetadataVO> list = new ArrayList<>();
                getChild(sysTotalList, apiMetadataVO.getId(), list, finalIsOrderEle, finalResIdsList);
                List<ApiMetadataVO> tempList = list.stream()
                        .filter((ApiMetadataVO log) -> log.getApiId() != null && log.getApiId().equals(apiMetadata.getApiId()))
                        .collect(Collectors.toList());
                resBody.addAll(tempList);
            } else {
                //只有网关查询用到urlBody
                if (finalGatewayQuery && !apiMetadataVO.getName().equals("body") &&
                        !apiMetadataVO.getName().equals("sysHead") &&
                        !apiMetadataVO.getName().equals("busHead") &&
                        !apiMetadataVO.getName().equals("responseData") &&
                        !apiMetadataVO.getName().equals("requestData")) {
                    //公共参数
                    if (apiMetadataVO.getGroupId() == null || apiMetadataVO.getGroupId() == 0L) {
                        urlBody.add(apiMetadataVO);
                        getChild(sysTotalList, apiMetadataVO.getId(), urlBody, 0, null);
                    }


                }

            }

        });
        if (apiMetadata.getBaseProductId() != null && gatewayId != 0L) {
            //2.api发布来查询----------再查公共参数的
            ApiMetadataVO apiMetadatas = new ApiMetadataVO();
            apiMetadatas.setGatewayId(gatewayId);
            urlBody.clear();
            List<ApiMetadataVO> list = apiMetadataService.selectApiMetadataList(apiMetadatas);
            list.forEach(apiMetadata1 -> {
                ApiMetadataVO apiMetadataVO = new ApiMetadataVO();
                BeanUtils.copyProperties(apiMetadata1, apiMetadataVO);
                apiMetadataVO.setParentId(apiMetadata1.getGroupId() == null ? 0L : apiMetadata1.getGroupId());
                if (!apiMetadataVO.getName().equals("body") &&
                        !apiMetadataVO.getName().equals("sysHead") &&
                        !apiMetadataVO.getName().equals("busHead") &&
                        !apiMetadataVO.getName().equals("responseData") &&
                        !apiMetadataVO.getName().equals("requestData")) {
                    //公共参数
                    urlBody.add(apiMetadataVO);
                    getChild(sysTotalList, apiMetadataVO.getId(), urlBody, 0, null);
                }

            });
        }

        Map map = new HashMap();
        //请求报文
        map.put("busReqHead", ApiMetadataWrapper.build().listNodeVOs(busReqHead));
        map.put("busResHead", ApiMetadataWrapper.build().listNodeVOs(busResHead));
        map.put("sysReqHead", ApiMetadataWrapper.build().listNodeVOs(sysReqHead));
        map.put("sysResHead", ApiMetadataWrapper.build().listNodeVOs(sysResHead));
        map.put("reqBody", ApiMetadataWrapper.build().listNodeVOs(reqBody));
        map.put("resBody", ApiMetadataWrapper.build().listNodeVOs(resBody));
        map.put("urlBody", ApiMetadataWrapper.build().listNodeVOs(urlBody));
        map.put("comReqBody", ApiMetadataWrapper.build().listNodeVOs(comReqBody));
        map.put("comResBody", ApiMetadataWrapper.build().listNodeVOs(comResBody));

        R r = new R();
        r.setSuccess(true);
        r.setMsg("操作成功");
        r.setData(map);
        return r;
    }


    /**
     * @Author wangjinghan
     * @Description 获取当前list
     * @param tempList sysReqHead\sysResHead等
     * @param finalIsOrderEle  订阅元素功能标志 1表示订阅元素查看  2 添加
     * @param finalIdsList  表示订阅元素查看时要回显的id
     * @param id 当前一层元素的节点
     * @date: 2020/11/5 9:22
     */
//    private void getChildData(List<ApiMetadataVO> tempList, int finalIsOrderEle, List<String> finalIdsList, ApiMetadataVO apiMetadataVO, Long id) {
//        tempList.add(apiMetadataVO);
//        List<ApiMetadataVO> ZS = new ArrayList<>();
//        tempList.addAll(getChild(id, ZS,finalIsOrderEle, finalIdsList));
//    }

//    /**
//     * @Author wangjinghan
//     * @Description  得到孩子节点
//     * @date: 2020/10/28 16:58
//     */
//    private List<ApiMetadataVO> getChild(Long groupId,List<ApiMetadataVO> apiMetadataVOList){
//      //  List<ApiMetadataVO> allList = new ArrayList<>();
//        ApiMetadataVO metadataVO = new ApiMetadataVO();
//        metadataVO.setGroupId(groupId);
//        List<ApiMetadataVO> voList = apiMetadataService.selectApiMetadataList(metadataVO);
//         for (int x = 0; x< voList.size(); x++) {
//             apiMetadataVOList.add(voList.get(x));
//                 getChild(voList.get(x).getId(),apiMetadataVOList);
//         }
//
//        return apiMetadataVOList;
//    }

    /**
     * @param finalIsOrderEle 订阅元素功能标志 1表示订阅元素查看  2 添加
     * @param finalIdsList    订阅元素功能 要回显的所有id
     * @param groupId         当前这层元素的节点
     * @param resultList      要返回的对象
     * @param sysTotalList    系统下所有的元素
     * @Author wangjinghan
     * @Description 得到子孙后代
     * @date: 2020/10/28 16:58
     */
    private List<ApiMetadataVO> getChild(List<ApiMetadataVO> sysTotalList, Long groupId, List<ApiMetadataVO> resultList, int finalIsOrderEle, List<String> finalIdsList) {
        //全部数据进行判断
        for (ApiMetadataVO apiMetadataVO : sysTotalList) {
            if (groupId.equals(apiMetadataVO.getGroupId())) {
                getChild(sysTotalList, apiMetadataVO.getId(), resultList, finalIsOrderEle, finalIdsList);
                apiMetadataVO.setParentId(apiMetadataVO.getGroupId());
                //----------------订阅元素  1查看、2 回显后添加---------------------------
                if (finalIsOrderEle == 1) {
                    //必填元素一定回显；非必填元素选中才回显
                    if ("false".equals(apiMetadataVO.getIsRequired())) {
                        //finalIdsList就是选中的元素id集合
                        if (finalIdsList.contains(apiMetadataVO.getId().toString())) {
                            resultList.add(apiMetadataVO);
                        }
                    } else {
                        resultList.add(apiMetadataVO);
                    }
                } else if (finalIsOrderEle == 2) {//add功能
                    if ("false".equals(apiMetadataVO.getIsRequired())) {
                        //回显全部，其中finalIdsList选中的元素要打勾
                        if (finalIdsList.contains(apiMetadataVO.getId().toString())) {
                            //isSelected 1表示选中--页面就是打勾
                            apiMetadataVO.setIsSelected("1");
                        }
                    }
                    resultList.add(apiMetadataVO);
                } else {
                    resultList.add(apiMetadataVO);
                }
            }
        }
        return resultList;
    }


    /**
     * @Author wangjinghan
     * @Description 标准接口定义导出文档
     * @date: 2020/11/4 17:35
     */
    @PostMapping("/downloadApi")
    public void download(ApiMetadataVO apiMetadata, HttpServletResponse response) {
        //----------------返回对象定义-------------
        List<ApiMetadataVO> sysReqHead = new ArrayList<>();
        List<ApiMetadataVO> sysResHead = new ArrayList<>();
        List<ApiMetadataVO> busReqHead = new ArrayList<>();
        List<ApiMetadataVO> busResHead = new ArrayList<>();
        List<ApiMetadataVO> reqBody = new ArrayList<>();
        List<ApiMetadataVO> resBody = new ArrayList<>();
        List<ApiMetadataVO> resultVoList = new ArrayList<>();//所有集合
        //api发布的报文映射配置查询时传入apiId
        Long sysId = 0L;
        if (apiMetadata.getApiId() != null) {
            sysId = apiMetadataService.findSysIdByApiId(apiMetadata.getApiId());
        }
        ApiMetadataVO apiMetadataVo = new ApiMetadataVO();
        apiMetadataVo.setSysId(sysId);
        List<ApiMetadataVO> sysTotalList = apiMetadataService.selectApiMetadataList(apiMetadataVo);

        sysTotalList.forEach(apiMetadata1 -> {
            ApiMetadataVO apiMetadataVO = new ApiMetadataVO();
            BeanUtils.copyProperties(apiMetadata1, apiMetadataVO);
            apiMetadataVO.setParentId(apiMetadata1.getGroupId() == null ? 0L : apiMetadata1.getGroupId());

            if ("sysHead".equals(apiMetadataVO.getName()) && 1 == apiMetadataVO.getBodyType()) {
                //sysReqHead
                sysReqHead.add(apiMetadataVO);
                getChild(sysTotalList, apiMetadataVO.getId(), sysReqHead, 0, null);

            } else if ("sysHead".equals(apiMetadataVO.getName()) && 2 == apiMetadataVO.getBodyType()) {
                //sysResHead
                sysResHead.add(apiMetadataVO);
                getChild(sysTotalList, apiMetadataVO.getId(), sysResHead, 0, null);
            } else if ("busHead".equals(apiMetadataVO.getName()) && 1 == apiMetadataVO.getBodyType()) {
                //busReqHead
                busReqHead.add(apiMetadataVO);
                List<ApiMetadataVO> list = new ArrayList<>();
                getChild(sysTotalList, apiMetadataVO.getId(), list, 0, null);
                List<ApiMetadataVO> tempList = list.stream()
                        .filter((ApiMetadataVO log) -> log.getBaseProductId() != null && log.getBaseProductId().equals(apiMetadata.getBaseProductId()))
                        .collect(Collectors.toList());
                busReqHead.addAll(tempList);
            } else if ("busHead".equals(apiMetadataVO.getName()) && 2 == apiMetadataVO.getBodyType()) {
                //busResHead
                busResHead.add(apiMetadataVO);
                List<ApiMetadataVO> list = new ArrayList<>();
                getChild(sysTotalList, apiMetadataVO.getId(), list, 0, null);
                List<ApiMetadataVO> tempList = list.stream()
                        .filter((ApiMetadataVO log) -> log.getBaseProductId() != null && log.getBaseProductId().equals(apiMetadata.getBaseProductId()))
                        .collect(Collectors.toList());
                busResHead.addAll(tempList);
            } else if ("body".equals(apiMetadataVO.getName()) && 1 == apiMetadataVO.getBodyType()) {
                //reqBody
                reqBody.add(apiMetadataVO);
                List<ApiMetadataVO> list = new ArrayList<>();
                getChild(sysTotalList, apiMetadataVO.getId(), list, 0, null);
                List<ApiMetadataVO> tempList = list.stream()
                        .filter((ApiMetadataVO log) -> log.getApiId() != null && log.getApiId().equals(apiMetadata.getApiId()))
                        .collect(Collectors.toList());
                reqBody.addAll(tempList);
            } else if ("body".equals(apiMetadataVO.getName()) && 2 == apiMetadataVO.getBodyType()) {
                //resBody
                resBody.add(apiMetadataVO);
                List<ApiMetadataVO> list = new ArrayList<>();
                getChild(sysTotalList, apiMetadataVO.getId(), list, 0, null);
                List<ApiMetadataVO> tempList = list.stream()
                        .filter((ApiMetadataVO log) -> log.getApiId() != null && log.getApiId().equals(apiMetadata.getApiId()))
                        .collect(Collectors.toList());
                resBody.addAll(tempList);
            }
        });
        resultVoList.addAll(sysReqHead);
        resultVoList.addAll(sysResHead);
        resultVoList.addAll(busReqHead);
        resultVoList.addAll(busResHead);
        resultVoList.addAll(reqBody);
        resultVoList.addAll(resBody);
        ExcelUtil<ApiMetadataVO> util = new ExcelUtil<>(ApiMetadataVO.class);
        util.exportExcel(resultVoList, "API标准接口定义信息表", response);
    }


    /**
     * 自定义分页 接口定义数据表
     */
    @GetMapping("/page")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "分页", notes = "传入apiMetadata")
    public R<IPage<ApiMetadataVO>> page(ApiMetadataVO apiMetadata, Query query) {
        IPage<ApiMetadataVO> pages = apiMetadataService.selectApiMetadataPage(Condition.getPage(query), apiMetadata);
        return R.data(pages);
    }

    /**
     * 新增 接口定义数据表
     */
    @PostMapping("/save")
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "新增", notes = "传入apiMetadata")
    public R save(@Valid @RequestBody ApiMetadata apiMetadata) {
        List<ApiMetadata> apiMetadataList = apiMetadataService.findOrderChild(apiMetadata);
        apiMetadata.setOrderField(apiMetadataList.size());
        return R.status(apiMetadataService.save(apiMetadata));
    }

    /**
     * 修改 接口定义数据表
     */
    @PostMapping("/update")
    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "修改", notes = "传入apiMetadata")
    public R update(@Valid @RequestBody ApiMetadata apiMetadata) {
        List<ApiMetadata> apiMetadataList = apiMetadataService.findOrderChild(apiMetadata);
        if (apiMetadata.getOrderField() < 0) {
            return R.fail("该字段已是第一个字段,不能再进行上移");
        }
        if (apiMetadata.getOrderField() >= apiMetadataList.size()) {
            return R.fail("该字段已是最后一个字段,不能再进行下移");
        }
        int flag = 0;
        for (int i = 0; i < apiMetadataList.size(); i++) {
            if (apiMetadata.getId().equals(apiMetadataList.get(i).getId())) {
                flag = i;
                break;
            }
        }
        apiMetadataList.remove(flag);
        apiMetadataList.add(apiMetadata.getOrderField(), apiMetadata);
        for (int i = 0; i < apiMetadataList.size(); i++) {
            ApiMetadata am = apiMetadataList.get(i);
            am.setOrderField(i);
            apiMetadataService.updateById(am);
        }
        return R.success("");
    }

    /**
     * 新增或修改 接口定义数据表
     */
    @PostMapping("/submit")
    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "新增或修改", notes = "传入apiMetadata")
    public R submit(@Valid @RequestBody ApiMetadata apiMetadata) {
        //创建body组intype类型为body
        apiMetadata.setInType("body");
        //创建body组数据类型为object
        apiMetadata.setType("object");
        apiMetadata.setIsRequired("true");
        if (apiMetadata.getGroupId() != null && apiMetadata.getGroupId() != 0L) {
            ApiMetadata pApiMetadata = apiMetadataService.getById(apiMetadata.getGroupId());
            if (pApiMetadata != null) {
                apiMetadata.setGroupId(pApiMetadata.getId());
                apiMetadata.setRef(pApiMetadata.getName());
            }
            apiMetadata.setIsRequired("true");
        }
        boolean result = apiMetadataService.saveOrUpdate(apiMetadata);
        if (result) {
            return R.data(apiMetadata);
        } else {
            return R.status(false);
        }

    }


    /**
     * 删除 接口定义数据表
     */
    @PostMapping("/remove")
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "逻辑删除", notes = "传入ids")
    @Transactional(rollbackFor = Exception.class)
    public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
        List<Long> list = Func.toLongList(ids);
        for (Long id : list) {
            if (apiMetadataService.findByGroupId(id).size() > 0) {
                return R.fail(0001, "存在子级数据，请先删除子级数据，再删除父级数据！");
            }
        }

        for (Long id : list) {
            ApiMetadata apiMetadata = apiMetadataService.getById(id);
            if (!apiMetadataService.removeById(apiMetadata.getId())) {
                return R.status(false);
            }
            List<ApiMetadata> apiMetadataList = apiMetadataService.findOrderChild(apiMetadata);
            for (int i = 0; i < apiMetadataList.size(); i++) {
                ApiMetadata am = apiMetadataList.get(i);
                am.setOrderField(i);
                apiMetadataService.updateById(am);
            }
        }
        return R.status(true);
    }

    /**
     * @param opcApiIdReq
     * @param ids
     * @return org.springblade.core.tool.api.R
     * @Description 请求参数批量添加元数据
     * @Author daina
     * @Date 10:47 2020/2/22
     **/
    @PostMapping("/addReqMetadata")
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "添加", notes = "opcApiIdReq,inType,ids")
    @ApiLog("接口请求参数批量添加元数据")
    @Log(title = "接口请求参数批量添加元数据", businessType = BusinessType.INSERT)
    @Transactional(rollbackFor = Exception.class)
    public R addReqMetadata(@ApiParam(name = "opcApiIdReq", value = "接口id") @RequestParam Long opcApiIdReq,
                            @ApiParam(name = "baseProductId", value = "基础产品id") Long baseProductId,
                            @ApiParam(name = "inType", value = "请求参数类型") @RequestParam String inType,
                            @ApiParam(name = "addType", value = "1-系统、2-网关、3-api") @RequestParam int addType,
                            @ApiParam(name = "parentId", value = "body请求父类id") @RequestParam Long parentId,
                            @ApiParam(name = "elementType", value = "1-数据元素、2-复合元素、3-复合结构体") @RequestParam String elementType,
                            @ApiParam(name = "apiComData", value = "api公共参数", required = false) @RequestParam String apiComData,
                            @ApiParam(value = "主键集合", required = true) @RequestParam String ids,
                            @ApiParam(value = "主键集合", required = true) @RequestParam Integer bodyType) {
        List<Long> metaIds = Func.toLongList(ids);//接收前台传过来的id集合
        List<Long> arrList = new LinkedList(metaIds);
        List<String> idsList1 = null;
        idsList1 = apiMetadataService.getApiIds(addType, baseProductId, opcApiIdReq, inType, bodyType, parentId, apiComData);//查询出符合条件的对象集合
        if (idsList1.size() > 0) {
            for (int i = 0; i < idsList1.size(); i++) {
                Long no1 = idsList1.get(i) == null ? null : Long.valueOf(idsList1.get(i));
                for (int j = 0; j < metaIds.size(); j++) {
                    Long no2 = metaIds.get(j);
                    if (no1 != null && no2 != null && no1.longValue() == no2.longValue()) {
                        arrList.remove(no2);
                        //System.out.println(metaIds);
                    }
                }
            }
        }
        List<ApiMetadata> apiMetadataList = apiMetadataService.findOrderChild(addType, baseProductId, opcApiIdReq, inType, bodyType, parentId);
        int metaSize = apiMetadataList.size();
        for (Long metaId : arrList) {
            ApiMetadata apiMetadata = new ApiMetadata();
            Metadata metadata = metadataService.getById(metaId);
            if (metadata.getIsRequired() == null || "".equals(metadata.getIsRequired())) {
                metadata.setIsRequired("false");
            }
            apiMetadata.setMetadataId(metaId);
            if (addType == 3) {
                //api
                apiMetadata.setApiId(opcApiIdReq);
                Long sysId = apiMetadataService.findSysIdByApiId(opcApiIdReq);
                apiMetadata.setSysId(sysId);
            } else if (addType == 2) {
                //网关
                apiMetadata.setGatewayId(opcApiIdReq);
            } else if (addType == 1) {
                //系统 或者 基础产品
                apiMetadata.setSysId(opcApiIdReq);
                if (baseProductId != null && baseProductId != 0) {
                    // 基础产品
                    apiMetadata.setBaseProductId(baseProductId);
                }
            }
            apiMetadata.setInType(inType);
            apiMetadata.setBodyType(bodyType);
            apiMetadata.setDefaultValue(metadata.getDefaultValue());
            apiMetadata.setDescription(metadata.getFieldName());
            apiMetadata.setFileEnum(metadata.getFieldEnum());
            if (parentId != null && parentId != 0) {
                ApiMetadata pApiMetadata = apiMetadataService.getById(parentId);
                if (pApiMetadata != null) {
                    apiMetadata.setGroupId(pApiMetadata.getId());
                    apiMetadata.setRef(pApiMetadata.getName());
                    apiMetadata.setIsRequired(metadata.getIsRequired());
                } else {
                    apiMetadata.setIsRequired(metadata.getIsRequired());
                }
            } else {
                apiMetadata.setGroupId(0L);
                apiMetadata.setIsRequired(metadata.getIsRequired());
            }
            if (apiComData.length() != 0) {
                apiMetadata.setApiComData(apiComData);
            }
            apiMetadata.setName(metadata.getFieldCode());
            apiMetadata.setType(metadata.getFieldType());
            apiMetadata.setTypeFormat(metadata.getTypeFormat());
            apiMetadata.setXmlName(metadata.getXmlName());
            apiMetadata.setXmlWrapped(metadata.getXmlWrapped());
            apiMetadata.setDescribe(metadata.getDescribe());
            if (metadata.getFieldLength() != null && !"".equals(metadata.getFieldLength())) {
                apiMetadata.setLength(Integer.valueOf(metadata.getFieldLength()));
            }
            apiMetadata.setOrderField(metaSize);
            if ("3".equals(elementType)) {
                //  如果是结构体类型 则生成id  用于后面子级元素的父ID
                String id = serialNumberService.generateSerialNumberByModelCode("opc_issue_api");
                apiMetadata.setId(Long.valueOf(id));
                apiMetadata.setType("string");
                apiMetadataService.save(apiMetadata);
            } else {
                apiMetadataService.saveOrUpdate(apiMetadata);
            }
            metaSize++;
            //  如果是结构体类型 则添加子级元素
            if ("3".equals(elementType)) {
                Long pid = apiMetadata.getId();
                MetadataVO metadataVO = new MetadataVO();
                metadataVO.setStructureId(metaId.toString());
                List<MetadataVO> lists = strucMetaMapper.listStructData(metadataVO);
                if (lists.size() > 0) {
                    for (MetadataVO vo : lists) {
                        ApiMetadata childMetadata = new ApiMetadata();
                        BeanUtils.copyProperties(apiMetadata, childMetadata);
                        childMetadata.setId(null);
                        childMetadata.setGroupId(pid);
                        childMetadata.setRef(apiMetadata.getName());
                        Metadata meta = metadataService.getById(vo.getId());
                        if (meta.getIsRequired() == null || "".equals(meta.getIsRequired())) {
                            childMetadata.setIsRequired(meta.getIsRequired());
                        }
                        childMetadata.setMetadataId(vo.getId());

                        if (meta.getDefaultValue() != null && !"".equals(meta.getDefaultValue())) {
                            childMetadata.setDefaultValue(meta.getDefaultValue());
                        }
                        childMetadata.setDescription(meta.getFieldName());
                        childMetadata.setFileEnum(meta.getFieldEnum());
                        childMetadata.setName(meta.getFieldCode());
                        childMetadata.setType(meta.getFieldType());
                        childMetadata.setTypeFormat(meta.getTypeFormat());
                        childMetadata.setXmlName(meta.getXmlName());
                        childMetadata.setXmlWrapped(meta.getXmlWrapped());
                        if (meta.getDescribe() != null && !"".equals(meta.getDescribe())) {
                            childMetadata.setDescribe(meta.getDescribe());
                        } else {
                            childMetadata.setDescribe(null);
                        }
                        if (meta.getFieldLength() != null && !"".equals(meta.getFieldLength())) {
                            childMetadata.setLength(Integer.valueOf(meta.getFieldLength()));
                        } else {
                            childMetadata.setLength(null);
                        }

                        childMetadata.setOrderField(metaSize);
                        apiMetadataService.save(childMetadata);
                        metaSize++;
                    }

                }
            }

        }
        return R.status(true);
    }


    /**
     * @param
     * @return org.springblade.core.tool.api.R<java.util.List < com.dhcc.bpm.modules.metadata.vo.MetadataVO>>
     * @Description 获取元数据树
     * @Author daina
     * @Date 10:46 2020/2/22
     **/
    @GetMapping("/tree")
    @ApiOperationSupport(order = 8)
    @ApiOperation(value = "获取元数据树", notes = "")
    @ApiLog("获取元数据树")
    @Log(title = "获取元数据树", businessType = BusinessType.SELECT)
    public R<List<ApiMetadataVO>> tree() {
        List<ApiMetadataVO> tree = apiMetadataService.tree();
        return R.data(tree);
    }


    /**
     * @param
     * @return true
     * @Description 根据字段映射关系, 生成报文配置
     * @Author zhangzexu
     * @Date 15:30 2020/2/28
     **/
    @GetMapping("/makePolicyXml")
    @ApiOperationSupport(order = 8)
    @ApiOperation(value = "生成报文配置的xml文件", notes = "")
    @ApiLog("生成报文配置的xml文件")
    @Log(title = "生成报文配置的xml文件", businessType = BusinessType.SELECT)
    public R makePolicyXml(@ApiParam(name = "apiId", value = "接口id") @RequestParam Long apiId, @ApiParam(name = "xmlType", value = "报文类型") @RequestParam String xmlType) {


        String space = "            ";


        List<ApiMetadata> apiMetadataList = apiMetadataService.findChildByApiId(apiId, 0L);


        List<String> messageChecks = apiMetadataMapperService.selectGroupBy(apiId);

        HashMap<String, Object> root = new HashMap<>();
        root.put("xmlType", xmlType);

        List<HashMap<String, Object>> xmlList = new ArrayList<>();
        StringBuilder firstWork = new StringBuilder();

        for (String messageCheck : messageChecks) {
            StringBuilder stringBuilderResp = new StringBuilder();
            StringBuilder stringBuilderReq = new StringBuilder();
            String sp = space;


            for (ApiMetadata apiMetadata : apiMetadataList) {
                if (apiMetadata.getBodyType() == 2) {

//                    ServerApiMetadata serverApiMetadata = serverApiMetadataService.findByServerApiId(apiId,apiMetadata.getId(),messageCheck);
//                stringBuilderResp.append(sp);
//                stringBuilderResp.append("<ITEM ");
//                stringBuilderResp.append(createItem(firstWork,xmlType,apiMetadata,serverApiMetadata));
//                stringBuilderResp.append(" type=\""+apiMetadata.getType()+"\"");
//                stringBuilderResp.append(">\n");
                    mapChilderMetadata(messageCheck, firstWork, xmlType, space, stringBuilderResp, apiId, apiMetadata.getId());
//                stringBuilderResp.append(sp);
//                stringBuilderResp.append("</ITEM>\n");
                } else {
//                    ServerApiMetadata serverApiMetadata = serverApiMetadataService.findByServerApiId(apiId,apiMetadata.getId(),messageCheck);
//                stringBuilderReq.append(sp);
//                stringBuilderReq.append("<ITEM ");
//                stringBuilderResp.append(createItem(firstWork,xmlType,apiMetadata,serverApiMetadata));
//                stringBuilderReq.append(">\n");
                    mapChilderMetadata(messageCheck, firstWork, xmlType, space, stringBuilderReq, apiId, apiMetadata.getId());
                    stringBuilderReq.append(sp);
//                stringBuilderReq.append("</ITEM>\n");
                }
            }

            HashMap<String, Object> maps = new HashMap<>();

            //拆包
            maps.put("ANALYZE", stringBuilderResp.toString());

            maps.put("ANALYZE_CHECK", messageCheck.split(";")[0]);
            maps.put("INTEGRATE_CHECK", messageCheck.split(";")[1]);
            // 组包
            maps.put("INTEGRATE", stringBuilderReq.toString());

            xmlList.add(maps);

        }
        root.put("datas", xmlList);
        root.put("FIRSTWORK", firstWork.toString());
        TemplateConfig.generate("apiCode.html", root, "/json/policyXml.ftl");

        return R.data(root, "success");
    }

    private void mapChilderMetadata(String messageCheck, StringBuilder firstWork, String xmlType, String space, StringBuilder stringBuilder, Long apiId, Long metadataId) {
        List<ApiMetadata> apiMetadataS = apiMetadataService.findChildByApiId(apiId, metadataId);
        for (ApiMetadata apiMetadata : apiMetadataS) {


            ServerApiMetadata serverApiMetadata = serverApiMetadataService.findByServerApiId(apiId, apiMetadata.getId(), messageCheck);
            if (serverApiMetadata == null) {
                continue;
            }

            String sp = space + "    ";
            stringBuilder.append(sp);
            stringBuilder.append("<ITEM ");

            stringBuilder.append(createItem(messageCheck, firstWork, xmlType, apiMetadata, serverApiMetadata));

            if (apiMetadata.getType().equals("object")) {
                stringBuilder.append(" type=\"" + apiMetadata.getType() + "\"");
                stringBuilder.append(">\n");
                mapChilderMetadata(messageCheck, firstWork, xmlType, space + "    ", stringBuilder, apiId, apiMetadata.getId());
                stringBuilder.append(sp);
                stringBuilder.append("</ITEM>\n");
            } else {
                stringBuilder.append("/>\n");
            }

        }
        return;
    }

    private String createItem(String messageCheck, StringBuilder firstWork, String xmlType, ApiMetadata apiMetadata, ServerApiMetadata serverApiMetadata) {

        ApiMetadataMapper apiMetadataMapper = apiMetadataMapperService.selectServerApiMetaData(serverApiMetadata.getApiId(), serverApiMetadata.getId(), messageCheck);
        if ("true".equals(apiMetadataMapper.getFirstWorkItem()) && !firstWork.toString().contains(apiMetadata.getName())) {
            firstWork.append("            <ITEM ");
            firstWork.append("name=\"" + apiMetadata.getName() + "\"");
            if ("xml".equals(xmlType) || "XML".equals(xmlType)) {
                firstWork.append(" path=\"" + getServerApiMetadataParent(serverApiMetadata.getName() + "/", serverApiMetadata) + "\"");
            } else if ("sep".equals(xmlType) || "SEP".equals(xmlType)) {
                firstWork.append(" len=\"" + 7 + "\"");
                firstWork.append(" begimIndex=\"" + 0 + "\"");
            } else if ("fixed".equals(xmlType) || "FIXED".equals(xmlType)) {
                firstWork.append(" len=\"" + apiMetadataMapper.getMessageIndex() + "\"");
            }
            firstWork.append("/>\n");
        }
        StringBuilder stringBuilder = new StringBuilder();
        if ("xml".equals(xmlType) || "XML".equals(xmlType)) {
            stringBuilder.append("name=\"" + serverApiMetadata.getName() + "\"");
            if (!apiMetadata.getName().equals(serverApiMetadata.getName())) {
                stringBuilder.append(" jname=\"" + apiMetadata.getName() + "\"");
            }
            stringBuilder.append(" path=\"" + getServerApiMetadataParent(serverApiMetadata.getName() + "/", serverApiMetadata) + "\"");

        } else if ("sep".equals(xmlType) || "SEP".equals(xmlType)) {
            stringBuilder.append("name=\"" + apiMetadata.getName() + "\"");
            stringBuilder.append(" seq=\"" + apiMetadataMapper.getMessageIndex() + "\"");
        } else if ("fixed".equals(xmlType) || "FIXED".equals(xmlType)) {
            stringBuilder.append("name=\"" + apiMetadata.getName() + "\"");
            stringBuilder.append(" len=\"" + apiMetadataMapper.getMessageIndex() + "\"");
        }
        return stringBuilder.toString();
    }

    private String getServerApiMetadataParent(String path, ServerApiMetadata serverApiMetadata) {

        ServerApiMetadata apiMetadata = serverApiMetadataService.getById(serverApiMetadata.getGroupId());
        path = apiMetadata.getName() + "/" + path;
        if (apiMetadata.getGroupId() > 0) {
            return getServerApiMetadataParent(path, apiMetadata) + "/" + path;
        } else {
            return path;
        }

    }

    @GetMapping("/queryOpenapi")
    @ApiOperationSupport(order = 9)
    @ApiOperation(value = "查询openaapi3.0文档", notes = "apiId")
    @ApiLog("查询openaapi3 3.0 文档")
    @Log(title = "查询openaapi3 3.0 文档", businessType = BusinessType.SELECT)
    public R queryOpenapi(@ApiParam(name = "apiId", value = "接口id") @RequestParam Long apiId) throws Exception {
        com.dhcc.bpm.modules.api.entity.Api api = apiService.getById(apiId);
        if(null == api){
            return R.data("");
        }
        return makeOpenApi(apiId);
    }


    @GetMapping("/makeOpenApi")
    @ApiOperationSupport(order = 9)
    @ApiOperation(value = "生成openaapi3.0文档", notes = "apiId")
    @ApiLog("生成openapi 3.0 文档")
    @Log(title = "生成openapi 3.0 文档", businessType = BusinessType.SELECT)
    public R makeOpenApi(@ApiParam(name = "apiId", value = "接口id") @RequestParam Long apiId) throws Exception {

        //创建api 基本信息
        com.dhcc.bpm.modules.api.entity.Api api = apiService.getById(apiId);
        OpenApiParameter.OpenApiParameterBuilder openApi = OpenApiParameter.builder().info(OpenApiParameter.Info.builder().title(api.getApiEname()).description(api.getApiName()).version(api.getApiVersion()).build());
        openApi.openapi("3.0.1");

        Gateway gateway = gatewayService.getById(api.getOpcGatewayId().split(",")[0]);
        Gateway testGateway = gatewayService.getById(api.getOpcGatewayIdTest().split(",")[0]);
        String url = "http://" + gateway.getGatewayIp() + ":" + gateway.getGatewayPort();
        String testUrl = "http://" + testGateway.getGatewayIp() + ":" + testGateway.getGatewayPort();
        //组装接口路径
        ArrayList<OpenApiParameter.Servers> arrayList = new ArrayList<>();
        arrayList.add(OpenApiParameter.Servers.builder().url(url).description(gateway.getGatewayName()).build());
        arrayList.add(OpenApiParameter.Servers.builder().url(testUrl).description(testGateway.getGatewayName()).build());
        openApi.servers(arrayList);

        //创建请求类型 post 、get 、put 、del
        OpenApiParameter.Method.MethodBuilder method = OpenApiParameter.Method.builder().operationId(api.getApiEname()).summary(api.getApiName());


        //创建query path 请求参数
        List<ApiMetadata> query = apiMetadataService.findOtherByApiId(apiId);

        List<OpenApiParameter.Parameters> queryParameters = new ArrayList<>();
        for (ApiMetadata pa1 : query) {
            log.info("quey ApiMetadata:{}", pa1);
            OpenApiParameter.Parameters parameters = OpenApiParameter.Parameters.builder().description(pa1.getDescription()).in(pa1.getInType()).name(pa1.getName()).required(Boolean.valueOf(pa1.getIsRequired())).schema(OpenApiParameter.Schema.builder().type(pa1.getType()).format(pa1.getTypeFormat()).build()).build();
            queryParameters.add(parameters);
        }
        method.parameters(queryParameters);

        //创建json 数据对象
//        List<ApiMetadata> parent = apiMetadataService.findReqObjectByApiId(apiId);
        Long sysId = apiMetadataService.findSysIdByApiId(apiId);
        if (sysId == null) {
            return R.fail(222, "该接口所属系统不存在！");
        }
        ApiMetadata apiMetadata = new ApiMetadata();
        apiMetadata.setSysId(sysId);
        //查出那8个对象 sysHead  busHead body requestData responseData
        List<ApiMetadataVO> parent = apiMetadataService.queryApiMetadataList(apiMetadata);
        if (parent.size() < 1) {
            return R.fail(222, "请先创建标准接口数据！");
        }
//        HashMap<String, OpenApiParameter.Schemas> schemasMap = new HashMap<>();
        HashMap<String, OpenApiParameter.Schemas> schemasMap = new HashMap<>();
        for (ApiMetadataVO pa1 : parent) {
            log.info("object ApiMetadata:{}", pa1);

            String name = pa1.getName();
            String type = pa1.getType();
            if ("list".equals(type)) {
                type = "object";
            }
            //head body requestData 等的子孙节点
            List<ApiMetadataVO> childern = apiMetadataService.findChildByGroupId(pa1.getId());
            if (childern.size() == 0) {
                continue;
            }
            OpenApiParameter.Schemas.SchemasBuilder schemas = null;
            if ("responseData".equals(name) || "requestData".equals(name)) {
                schemas = OpenApiParameter.Schemas.builder().description(pa1.getDescription()).type(type).xml(OpenApiParameter.Xml.builder().name(pa1.getXmlName()).build());
            } else {
                schemas = OpenApiParameter.Schemas.builder().description(pa1.getDescription()).type(type).xml(OpenApiParameter.Xml.builder().name(pa1.getXmlName() + pa1.getBodyType()).build());
            }

            //添加必填参数校验
            List<String> required = new ArrayList<>();
            //head body等的子孙节点存起来
            HashMap<String, OpenApiParameter.Schema> propertiesMap = new HashMap<>();

//            List<ApiMetadata> childern = apiMetadataService.findChildByApiId(apiId, pa1.getId());

            for (ApiMetadataVO child : childern) {
                log.info("node ApiMetadata:{}", child);

                if ("object".equals(child.getType())) {
                    List<ApiMetadataVO> childern2 = apiMetadataService.findChildByGroupId(child.getId());
                    if (childern2.size() > 0) {
                        if ("responseData".equals(name) || "requestData".equals(name)) {
                            propertiesMap.put(child.getName(), OpenApiParameter.Schema.builder().ref("#/components/schemas/" + child.getName() + child.getBodyType()).build());
                        } else {
                            //判断孩子是否有子孙及节点，没有就不给生成
                            propertiesMap.put(child.getName(), OpenApiParameter.Schema.builder().ref("#/components/schemas/" + child.getName()).build());
                        }
                    }
                } else if ("enum".equals(child.getType())) {
                    propertiesMap.put(child.getName(), OpenApiParameter.Schema.builder().type(child.getTypeFormat()).description(child.getDescription()).xml(OpenApiParameter.Xml.builder().name(child.getName()).wrapped(Boolean.valueOf(child.getXmlWrapped())).build()).Enum(Arrays.asList(333, 44)).build());
                    if (Boolean.valueOf(child.getIsRequired())) {
                        required.add(child.getName());
                    }
                } else if ("array".equals(child.getType()) || "list".equals(child.getType())) {
                    OpenApiParameter.Items.ItemsBuilder itemsBuilder = OpenApiParameter.Items.builder();
                    if ("object".equals(child.getTypeFormat())) {
                        //查出这个对应的组
                        itemsBuilder.ref("#/components/schemas/");
                    } else {
                        itemsBuilder.type(child.getTypeFormat());
                    }
                    propertiesMap.put(child.getName(), OpenApiParameter.Schema.builder().type("array").description(child.getDescription()).xml(OpenApiParameter.Xml.builder().name(child.getName()).wrapped(Boolean.valueOf(child.getXmlWrapped())).build()).items(itemsBuilder.build()).build());
                    if (!"object".equals(child.getTypeFormat())) {
                        if (Boolean.valueOf(child.getIsRequired())) {
                            required.add(child.getName());
                        }
                    }
                } else {
                    propertiesMap.put(child.getName(), OpenApiParameter.Schema.builder().type(child.getType()).description(child.getDescription()).format(child.getTypeFormat()).xml(OpenApiParameter.Xml.builder().name(child.getName()).wrapped(Boolean.valueOf(child.getXmlWrapped())).build()).build());
                    if (Boolean.valueOf(child.getIsRequired())) {
                        required.add(child.getName());
                    }
                }
            }

            if ("requestData".equals(name)) {//请求公共参数
                getManyZSNode(apiId, required, propertiesMap, "req", schemasMap);
            } else if ("responseData".equals(name)) {//响应公共参数
                getManyZSNode(apiId, required, propertiesMap, "res", schemasMap);
            }

            if (!required.isEmpty()) {
                schemas.required(required);
            }
            schemas.properties(propertiesMap);
            if ("responseData".equals(name) || "requestData".equals(name)) {
                schemasMap.put(name, schemas.build());
            } else {
                schemasMap.put(name + pa1.getBodyType(), schemas.build());
            }

        }

        //通过apiId查到网关Id,然后去查询网关公共参数
        HashMap<String, OpenApiParameter.Schemas> wgSchemasMap = new HashMap<>();
        ApiVO apis = new ApiVO();
        List<Long> apiIds = new ArrayList<>();
        apiIds.add(apiId);
        apis.setApiIds(apiIds);
        List<ApiVO> apiVOList = apiService.selectApiList(apis);
        if (apiVOList.size() == 1) {
            String[] gatewayIds = apiVOList.get(0).getOpcGatewayId().split(",");
            Long gatewayId = Long.valueOf(gatewayIds[0]);
            ApiMetadataVO apiMetadata1 = new ApiMetadataVO();
            apiMetadata1.setGatewayId(gatewayId);
            List<ApiMetadataVO> gatewayMetadata = apiMetadataService.selectApiMetadataList(apiMetadata1);
            //有祖孙节点
            for (ApiMetadataVO child : gatewayMetadata) {
                if (child.getGroupId() == null || child.getGroupId() == 0L) {
                    //是父节点
                    OpenApiParameter.Schemas.SchemasBuilder schemas2 = OpenApiParameter.Schemas.builder().type("object").description(child.getDescription()).xml(OpenApiParameter.Xml.builder().name(child.getXmlName()).build());
                    int num = 0;
                    childDataByGateway(schemasMap, wgSchemasMap, child, schemas2, num);
                }
            }
        }

        OpenApiParameter.Schemas.SchemasBuilder schemasRequestBody = OpenApiParameter.Schemas.builder().type("object").xml(OpenApiParameter.Xml.builder().name(api.getApiEname() + "Req").build());
//        HashMap<String, OpenApiParameter.Schema> propertiesMap = new HashMap<>();
//        propertiesMap.put("requestData", OpenApiParameter.Schema.builder().ref("#/components/schemas/requestData1").build());
//        Iterator it = wgSchemasMap.keySet().iterator();
//        while(it.hasNext()){
//            String key=(String)it.next();
//            propertiesMap.put(key, OpenApiParameter.Schema.builder().ref("#/components/schemas/"+key).build());
//        }
        HashMap<String, OpenApiParameter.Schema> propertiesMap = new HashMap<>();
        List<String> reqList = new ArrayList<>();
        propertiesMap.put("requestData", OpenApiParameter.Schema.builder().ref("#/components/schemas/requestData").build());
        Iterator it = wgSchemasMap.keySet().iterator();
        while (it.hasNext()) {
            String key = (String) it.next();
            OpenApiParameter.Schemas schema = wgSchemasMap.get(key);
            if (schema != null) {
                propertiesMap.put(key, OpenApiParameter.Schema.builder().xml(OpenApiParameter.Xml.builder().name(schema.getXml().getName()).build()).description(schema.getDescription()).type(schema.getType()).build());
                schema.getRequired().forEach(s -> reqList.add(s));
            }
        }
        schemasRequestBody.properties(propertiesMap);
        schemasRequestBody.required(reqList);
        schemasMap.put(api.getApiEname() + "Req", schemasRequestBody.build());

        OpenApiParameter.Schemas.SchemasBuilder schemasResponseBody = OpenApiParameter.Schemas.builder().type("object").xml(OpenApiParameter.Xml.builder().name(api.getApiEname() + "Res").build());
        HashMap<String, OpenApiParameter.Schema> propertiesMap2 = new HashMap<>();
        propertiesMap2.put("responseData", OpenApiParameter.Schema.builder().ref("#/components/schemas/responseData").build());

//        Iterator it2 = wgSchemasMap.keySet().iterator();
//        while(it2.hasNext()){
//            String key=(String)it2.next();
//            propertiesMap2.put(key, OpenApiParameter.Schema.builder().ref("#/components/schemas/"+key).build());
//        }
        Iterator it2 = wgSchemasMap.keySet().iterator();
        List<String> resList = new ArrayList<>();
        while (it2.hasNext()) {
            String key = (String) it2.next();
            OpenApiParameter.Schemas schema = wgSchemasMap.get(key);
            if (schema != null) {
                propertiesMap2.put(key, OpenApiParameter.Schema.builder().xml(OpenApiParameter.Xml.builder().name(schema.getXml().getName()).build()).description(schema.getDescription()).type(schema.getType()).build());
                schema.getRequired().forEach(s -> resList.add(s));
            }
        }
        schemasResponseBody.properties(propertiesMap2);
        schemasResponseBody.required(resList);
        schemasMap.put(api.getApiEname() + "Res", schemasResponseBody.build());

        //json 对象构建

        OpenApiParameter.Components components = OpenApiParameter.Components.builder().schemas(schemasMap).build();
        openApi.components(components);

        //组装body 参数
        {
            ApiMetadata reqRef = apiMetadataService.findParentObjectByApiId(apiId);

            HashMap<String, OpenApiParameter.RequestBodySchema> schemaHashMap = new HashMap<>();
            if (reqRef != null) {
                schemaHashMap.put("application/json", OpenApiParameter.RequestBodySchema.builder().schema(OpenApiParameter.Schema.builder().ref("#/components/schemas/" + reqRef.getName()).build()).build());
                schemaHashMap.put("application/xml", OpenApiParameter.RequestBodySchema.builder().schema(OpenApiParameter.Schema.builder().ref("#/components/schemas/" + reqRef.getName()).build()).build());
                OpenApiParameter.RequestBody requestBody = OpenApiParameter.RequestBody.builder().description(reqRef.getDescription()).content(schemaHashMap).required(true).build();
                method.requestBody(requestBody);
            } else {
                schemaHashMap.put("application/json", OpenApiParameter.RequestBodySchema.builder().schema(OpenApiParameter.Schema.builder().ref("#/components/schemas/" + api.getApiEname() + "Req").build()).build());
                schemaHashMap.put("application/xml", OpenApiParameter.RequestBodySchema.builder().schema(OpenApiParameter.Schema.builder().ref("#/components/schemas/" + api.getApiEname() + "Req").build()).build());
                OpenApiParameter.RequestBody requestBody = OpenApiParameter.RequestBody.builder().description("请求报文").content(schemaHashMap).required(true).build();
                method.requestBody(requestBody);
            }

        }

        //组装响应参数
        {

            ApiMetadata respRef = apiMetadataService.findResObjectByApiId(apiId);
            HashMap<String, OpenApiParameter.RequestBodySchema> schemaHashMap = new HashMap<>();
            if (respRef != null) {
                schemaHashMap.put("application/json", OpenApiParameter.RequestBodySchema.builder().schema(OpenApiParameter.Schema.builder().ref("#/components/schemas/" + respRef.getName()).build()).build());
                schemaHashMap.put("application/xml", OpenApiParameter.RequestBodySchema.builder().schema(OpenApiParameter.Schema.builder().ref("#/components/schemas/" + respRef.getName()).build()).build());
            } else {
                schemaHashMap.put("application/json", OpenApiParameter.RequestBodySchema.builder().schema(OpenApiParameter.Schema.builder().ref("#/components/schemas/" + api.getApiEname() + "Res").build()).build());
                schemaHashMap.put("application/xml", OpenApiParameter.RequestBodySchema.builder().schema(OpenApiParameter.Schema.builder().ref("#/components/schemas/" + api.getApiEname() + "Res").build()).build());
            }


            HashMap<String, OpenApiParameter.Responses> mps = new HashMap<>();

            mps.put("200", OpenApiParameter.Responses.builder().description("返回成功").content(schemaHashMap).build());

            mps.put("500", OpenApiParameter.Responses.builder().description("返回成功").build());

            method.responses(mps);
        }

        // 路径信息组装
        {
            HashMap<String, OpenApiParameter.Paths> hashMap = new HashMap<>();
            OpenApiParameter.Paths.PathsBuilder paths = OpenApiParameter.Paths.builder();
            if (api.getRequestMethod() == null) {
                api.setRequestMethod(2);
            }
            //请求类型
            switch (api.getRequestMethod()) {
                case 1:  //1: GET
                    paths.get(method.build());
                    break;
                case 2://2: POST
                    paths.post(method.build());
                    break;
                case 3://3: PUT
                    paths.put(method.build());
                    break;
                case 4://4: DELETE
                    paths.delete(method.build());
                    break;
                default:
                    paths.post(method.build());
                    break;
            }

            hashMap.put(api.getApiPath(), paths.build());
            openApi.paths(hashMap).build();
        }

        String result = JSON.toJSONString(openApi.build()).replaceAll("ref", "\\$ref");
        log.info("result {}", result);

        //保存json格式数据
        strToTxt( api.getApiCode(), result);

        return R.data(result);
    }

    @Async
    public void strToTxt(String apiCode, String yamlMsg){
        String pathUrl = path + "/" + apiCode + "/";
        File filePath = new File(pathUrl);
        if (!filePath.exists()) {
            if (!filePath.mkdirs()) {
                log.info("创建文件失败");
            }
        }
        File file = new File(pathUrl + apiCode + ".txt");
        try(PrintStream ps = new PrintStream(new FileOutputStream(file));){
            ps.println(yamlMsg);
            ps.flush();
        }catch (Exception e){
            log.error("保存openapi3.0json格式文件失败", e);
        }

    }

    /**
     * @Author wangjinghan
     * @Description 找出公共参数的子孙节点
     * @param:
     * @return:
     * @date: 2021/4/28 16:14
     */
    private void getManyZSNode(Long apiId, List<String> required, HashMap<String, OpenApiParameter.Schema> propertiesMap, String dataType, HashMap<String, OpenApiParameter.Schemas> schemasMap) {

        ApiMetadataVO apiV = new ApiMetadataVO();
        apiV.setApiComData(dataType + apiId);
        apiV.setGroupId(0L);
        //查出第一层
        List<ApiMetadataVO> comReqBody = apiMetadataService.selectApiMetadataList(apiV);
        for (ApiMetadataVO child : comReqBody) {
            List<ApiMetadataVO> childern2 = apiMetadataService.findChildByGroupId(child.getId());
            //判断孩子是否有子孙及节点
            if (childern2.size() == 0) {
                //没有就直接添加
                propertiesMap.put(child.getName(), OpenApiParameter.Schema.builder().type(child.getType()).description(child.getDescription()).format(child.getTypeFormat()).xml(OpenApiParameter.Xml.builder().name(child.getName()).wrapped(Boolean.valueOf(child.getXmlWrapped())).build()).build());
                if (Boolean.valueOf(child.getIsRequired())) {
                    required.add(child.getName());
                }
            } else {
                OpenApiParameter.Schemas.SchemasBuilder schemas2 = OpenApiParameter.Schemas.builder().type("object").description(child.getDescription()).xml(OpenApiParameter.Xml.builder().name(child.getXmlName() + child.getBodyType()).build());
                //有祖孙节点
                childData(schemasMap, child, schemas2);
                propertiesMap.put(child.getName() + child.getBodyType(), OpenApiParameter.Schema.builder().ref("#/components/schemas/" + child.getName() + child.getBodyType()).build());
            }
        }
    }

    @PostMapping("createOpenApiYaml")
    @ApiOperationSupport(order = 9)
    @ApiOperation(value = "生成yaml文档、html文档和word文档", notes = "yamlMsg，APIId")
    @ApiLog("生成yaml文档、html文档和word文档")
    @Log(title = "生成yaml文档、html文档和word文档", businessType = BusinessType.OTHER)
    public R createOpenApiYaml(@Valid @RequestBody ApiMetadataVO apiMetadataVO) throws IOException {
        PrintStream ps = null;
        String pathUrl = "";
        com.dhcc.bpm.modules.api.entity.Api api = null;
        try {
            api = apiService.getById(apiMetadataVO.getApiId());
            pathUrl = path + "/" + api.getApiCode();
            File filePath = new File(pathUrl);
            if (!filePath.exists()) {
                if (!filePath.mkdirs()) {
                    return R.fail("文件创建失败!");
                }
            }
            File file = new File(pathUrl + "/apiCode.yaml");
            ps = new PrintStream(new FileOutputStream(file));
            ps.println(apiMetadataVO.getYamlMsg());
            ps.flush();

            api.setOpenapiPath(pathUrl + "/apiCode.yaml");
            apiService.updateById(api);

            Map jsonMsg = FastJsonUtils.json2map(apiMetadataVO.getJsonMsg().replaceAll("\\$ref", "ref"));

            if (!StringUtils.isBlank(apiMetadataVO.getJsonMsg())) {
                TemplateConfig.generate(pathUrl + "/apiCode.html", jsonMsg, "/json/api.ftl");
                WorldUtils.htmlToWord("apiCode.doc", pathUrl + "/", FileUtils.readFileToString(new File(pathUrl + "/apiCode.html")));
            }
            jsonMsg = null;
        } catch (Exception e) {
            log.error("写入数据失败:{}", e);
            return R.fail("生成文档失败:" + e.getMessage());
        } finally {
            if (ps != null) {
                ps.close();
            }

            //本地生成完,再放到文件服务器  把3个文件分别上传,Plupload表的3个id以逗号形式存在api表中
//            List list = com.dhcc.bpm.common.utils.FileUtils.getFile(pathUrl, 1);
//            StringBuffer fileIds = new StringBuffer();
//            for (int i = 0; i < list.size(); i++) {
//                String fileName = (String) list.get(i);
//                Long id = upLoadServer(pathUrl, fileName);
//                if(id != null){
//                    fileIds.append(id.toString());
//                    if (i != list.size() - 1) {
//                        fileIds.append(",");
//                    }
//                }
//            }
//            if (api.getFileIds() != null) {
//                //删除原来下载的文件
//                String[] files = api.getFileIds().split(",");
//                for (String id : files) {
//                    pluploadMapper.deleteById(Long.valueOf(id));
//                }
//            }
//            api.setFileIds(fileIds.toString());
//            apiService.saveOrUpdate(api);
        }
        return R.success("生成文档成功");
    }


    @PostMapping("createOpenApiServer")
    @ApiOperationSupport(order = 9)
    @ApiOperation(value = "根据yaml生成服务端代码", notes = "yaml,Server")
    @ApiLog("根据yaml生成服务端代码")
    @Log(title = "根据yaml生成服务端代码", businessType = BusinessType.OTHER)
    public R createOpenApiServer(@Valid @RequestBody ApiMetadataVO apiMetadataVO) {
//        String gitPath = "https://gitee.com/zhangzexu/blog-parent.git";
        String privateKeyValue = privateKeyValueSet;
        com.dhcc.bpm.modules.api.entity.Api api = apiService.getById(apiMetadataVO.getApiId());
        BaseProduct baseProduct = baseProductService.getById(api.getBackserviceId());
        List<ProdCode> prodCode = new ArrayList<>();
        try {
            prodCode = prodCodeService.getProdCode(baseProduct.getProductName());
            if (prodCode.isEmpty()) {
                return R.fail("未配置api对应产品源码管理信息，请先在源码管理进行配置");
            }

            System.out.println(prodCode.get(0) + "-----");

            String gitPath = prodCode.get(0).getGitAddress();
            String gitUsername = prodCode.get(0).getGituserName();
            String gitPassword = ProdCodeController.decrypt(prodCode.get(0).getGitPassword(), privateKeyValue);
            String localPath = "";

            if (!prodCodePath.endsWith("/")) {
                localPath = prodCodePath + "/";
            } else {
                localPath = prodCodePath;
            }

            String[] s = gitPath.split("/");
            //代码的项目名称
            String project = s[s.length - 1].replace(".git", "");


            localPath = localPath + project;

            String pathUrl = path + "/" + api.getApiCode() + "/apiCode.yaml";


            R r = JGitUtil.pull(gitUsername, gitPassword, "develop", localPath);
            if (!r.isSuccess()) {
                return r;
            }

            log.info("该apiyaml 文档的位置为:{}", pathUrl);
            r = openapiGeneratorUtils.makeOpenapiServer(pathUrl, localPath, prodCode.get(0).getGroupId(), prodCode.get(0).getArtifactId(), prodCode.get(0).getArtifactVersion(), prodCode.get(0).getInvokerPackage(), prodCode.get(0).getInvokerPackage(), prodCode.get(0).getInvokerPackage());

            return r;
        } catch (Exception e) {
            log.error("代码生成失败:{}", e);
            return R.fail("代码生成失败");
        }
//        return R.success("server端代码生成成功");
    }


    @PostMapping("commitServerCode")
    @ApiOperationSupport(order = 9)
    @ApiOperation(value = "提交服务端生成的代码到git", notes = "git,Server")
    @ApiLog("提交服务端代码到git")
    @Log(title = "提交服务端代码到git", businessType = BusinessType.OTHER)
    public R commitServerCode(@Valid @RequestBody ApiMetadataVO apiMetadataVO) {
        String privateKeyValue = privateKeyValueSet;
        com.dhcc.bpm.modules.api.entity.Api api = apiService.getById(apiMetadataVO.getApiId());
        BaseProduct baseProduct = baseProductService.getById(api.getBackserviceId());
        List<ProdCode> prodCode = new ArrayList<>();
        try {
            prodCode = prodCodeService.getProdCode(baseProduct.getProductName());
            if (prodCode.isEmpty()) {
                return R.fail("api对应产品查询失败");
            }

            String gitPath = prodCode.get(0).getGitAddress();
            String gitUsername = prodCode.get(0).getGituserName();
            String gitPassword = ProdCodeController.decrypt(prodCode.get(0).getGitPassword(), privateKeyValue);

            String localPath = "";

            if (!prodCodePath.endsWith("/")) {
                localPath = prodCodePath + "/";
            } else {
                localPath = prodCodePath;
            }

            String[] s = gitPath.split("/");
            //代码的项目名称
            String project = s[s.length - 1].replace(".git", "");


            localPath = localPath + project;

            //创建代码
            R r = JGitUtil.commitAndPush(gitUsername, gitPassword, ".", api.getApiName() + " server代码创建", localPath);
            return r;
        } catch (Exception e) {
            log.error("代码上传失败:{}", e);
            return R.fail("代码上传失败");
        }
    }


    /**
     * 根据产品Id 查出api,生成json格式的openapi3.0文档
     */
    @GetMapping("/makeProOpenApi")
    @ApiOperationSupport(order = 9)
    @ApiOperation(value = "生成openaapi3.0文档", notes = "productId")
    @ApiLog("生成openapi 3.0 文档")
    @Log(title = "生成openapi 3.0 文档", businessType = BusinessType.SELECT)
    public R makeProOpenApi(@ApiParam(name = "productId", value = "产品id") @RequestParam Long productId) throws Exception {

        //创建product基本信息
        Product product = productService.getById(productId);
        if (product == null) {
            return R.fail(222, "该应用产品不存在");
        }
        OpenApiParameter.OpenApiParameterBuilder openApi = OpenApiParameter.builder().info(OpenApiParameter.Info.builder().title(product.getProductEname()).description(product.getProductName()).version(product.getProductVersion()).build());
        openApi.openapi("3.0.1");

        //模块划分
        ArrayList<OpenApiParameter.Tags> tags = new ArrayList<OpenApiParameter.Tags>();
        tags.add(OpenApiParameter.Tags.builder().name(product.getProductName()).description(product.getDescribe()).build());
        openApi.tags(tags);

        //根据应用产品查询关联api
        ProductApi productApi = new ProductApi();
        productApi.setProductId(productId);
        List<ProductApi> productApiList = productApiService.listProductApi(productApi);
        ArrayList<OpenApiParameter.Servers> arrayList = new ArrayList<>();
        HashMap<String, OpenApiParameter.Paths> hashMap = new HashMap<>();
        HashMap<String, OpenApiParameter.Schemas> schemasMap = new HashMap<>();
        for (int i = 0; i < productApiList.size(); i++) {
            Long apiId = productApiList.get(i).getApiId();
            com.dhcc.bpm.modules.api.entity.Api api = apiService.getById(apiId);
            if (api == null) {
                continue;
            }
            Gateway gateway = gatewayService.getById(api.getOpcGatewayId());
            Gateway testGateway = gatewayService.getById(api.getOpcGatewayIdTest());
            String url = "http://" + gateway.getGatewayIp() + ":" + gateway.getGatewayPort();
            String testUrl = "http://" + testGateway.getGatewayIp() + ":" + testGateway.getGatewayPort();
            //组装接口路径
            arrayList.add(OpenApiParameter.Servers.builder().url(url).description(gateway.getGatewayName()).build());
            arrayList.add(OpenApiParameter.Servers.builder().url(testUrl).description(testGateway.getGatewayName()).build());
            openApi.servers(arrayList);

            //创建请求类型 post 、get 、put 、del
            OpenApiParameter.Method.MethodBuilder method = OpenApiParameter.Method.builder().operationId(api.getApiEname()).summary(api.getApiName());


            //创建query path 请求参数
            List<ApiMetadata> query = apiMetadataService.findOtherByApiId(apiId);

            List<OpenApiParameter.Parameters> queryParameters = new ArrayList<>();
            for (ApiMetadata pa1 : query) {
                log.info("quey ApiMetadata:{}", pa1);
                OpenApiParameter.Parameters parameters = OpenApiParameter.Parameters.builder().description(pa1.getDescription()).in(pa1.getInType()).name(pa1.getName()).required(Boolean.valueOf(pa1.getIsRequired())).schema(OpenApiParameter.Schema.builder().type(pa1.getType()).format(pa1.getTypeFormat()).build()).build();
                queryParameters.add(parameters);
            }
            method.parameters(queryParameters);

            //创建json 数据对象
//        List<ApiMetadata> parent = apiMetadataService.findReqObjectByApiId(apiId);
            Long sysId = apiMetadataService.findSysIdByApiId(apiId);
            if (sysId == null) {
                return R.fail(222, "该接口所属系统不存在！");
            }
            ApiMetadata apiMetadata = new ApiMetadata();
            apiMetadata.setSysId(sysId);
            //查出那8个对象 sysHead  busHead body requestData responseData
            List<ApiMetadataVO> parent = apiMetadataService.queryApiMetadataList(apiMetadata);
            if (parent.size() < 1) {
                return R.fail(222, "请先创建标准接口数据！");
            }
            for (ApiMetadataVO pa1 : parent) {
                log.info("object ApiMetadata:{}", pa1);

                String name = pa1.getName();
                String type = pa1.getType();
                if ("list".equals(type)) {
                    type = "object";
                }
                //head body requestData 等的子孙节点
                List<ApiMetadataVO> childern = apiMetadataService.findChildByGroupId(pa1.getId());
                if (childern.size() == 0) {
                    continue;
                }
                OpenApiParameter.Schemas.SchemasBuilder schemas = null;
                if ("responseData".equals(name) || "requestData".equals(name)) {
                    schemas = OpenApiParameter.Schemas.builder().description(pa1.getDescription()).type(type).xml(OpenApiParameter.Xml.builder().name(pa1.getXmlName()).build());
                } else {
                    schemas = OpenApiParameter.Schemas.builder().description(pa1.getDescription()).type(type).xml(OpenApiParameter.Xml.builder().name(pa1.getXmlName() + pa1.getBodyType()).build());
                }

                //添加必填参数校验
                List<String> required = new ArrayList<>();
                //head body等的子孙节点存起来
                HashMap<String, OpenApiParameter.Schema> propertiesMap = new HashMap<>();


                for (ApiMetadataVO child : childern) {
                    log.info("node ApiMetadata:{}", child);

                    if ("object".equals(child.getType())) {
                        List<ApiMetadataVO> childern2 = apiMetadataService.findChildByGroupId(child.getId());
                        if (childern2.size() > 0) {
                            if ("responseData".equals(name) || "requestData".equals(name)) {
                                propertiesMap.put(child.getName(), OpenApiParameter.Schema.builder().ref("#/components/schemas/" + child.getName() + child.getBodyType()).build());
                            } else {
                                //判断孩子是否有子孙及节点，没有就不给生成
                                propertiesMap.put(child.getName(), OpenApiParameter.Schema.builder().ref("#/components/schemas/" + child.getName()).build());
                            }
                        }
                    } else if ("enum".equals(child.getType())) {
                        propertiesMap.put(child.getName(), OpenApiParameter.Schema.builder().type(child.getTypeFormat()).description(child.getDescription()).xml(OpenApiParameter.Xml.builder().name(child.getName()).wrapped(Boolean.valueOf(child.getXmlWrapped())).build()).Enum(Arrays.asList(333, 44)).build());
                        if (Boolean.valueOf(child.getIsRequired())) {
                            required.add(child.getName());
                        }
                    } else if ("array".equals(child.getType()) || "list".equals(child.getType())) {
                        OpenApiParameter.Items.ItemsBuilder itemsBuilder = OpenApiParameter.Items.builder();
                        if ("object".equals(child.getTypeFormat())) {
                            //查出这个对应的组
                            itemsBuilder.ref("#/components/schemas/");
                        } else {
                            itemsBuilder.type(child.getTypeFormat());
                        }
                        propertiesMap.put(child.getName(), OpenApiParameter.Schema.builder().type("array").description(child.getDescription()).xml(OpenApiParameter.Xml.builder().name(child.getName()).wrapped(Boolean.valueOf(child.getXmlWrapped())).build()).items(itemsBuilder.build()).build());
                        if (!"object".equals(child.getTypeFormat())) {
                            if (Boolean.valueOf(child.getIsRequired())) {
                                required.add(child.getName());
                            }
                        }
                    } else {
                        propertiesMap.put(child.getName(), OpenApiParameter.Schema.builder().type(child.getType()).description(child.getDescription()).format(child.getTypeFormat()).xml(OpenApiParameter.Xml.builder().name(child.getName()).wrapped(Boolean.valueOf(child.getXmlWrapped())).build()).build());
                        if (Boolean.valueOf(child.getIsRequired())) {
                            required.add(child.getName());
                        }
                    }
                }

                if ("requestData".equals(name)) {//请求公共参数
                    getManyZSNode(apiId, required, propertiesMap, "req", schemasMap);
                } else if ("responseData".equals(name)) {//响应公共参数
                    getManyZSNode(apiId, required, propertiesMap, "res", schemasMap);
                }

                if (!required.isEmpty()) {
                    schemas.required(required);
                }
                schemas.properties(propertiesMap);
                if ("responseData".equals(name) || "requestData".equals(name)) {
                    schemasMap.put(name, schemas.build());
                } else {
                    schemasMap.put(name + pa1.getBodyType(), schemas.build());
                }

            }

            //通过apiId查到网关Id,然后去查询网关公共参数
            HashMap<String, OpenApiParameter.Schemas> wgSchemasMap = new HashMap<>();
            ApiVO apis = new ApiVO();
            List<Long> apiIds = new ArrayList<>();
            apiIds.add(apiId);
            apis.setApiIds(apiIds);
            List<ApiVO> apiVOList = apiService.selectApiList(apis);
            if (apiVOList.size() == 1) {
                String[] gatewayIds = apiVOList.get(0).getOpcGatewayId().split(",");
                Long gatewayId = Long.valueOf(gatewayIds[0]);
                ApiMetadataVO apiMetadata1 = new ApiMetadataVO();
                apiMetadata1.setGatewayId(gatewayId);
                List<ApiMetadataVO> gatewayMetadata = apiMetadataService.selectApiMetadataList(apiMetadata1);
                //有祖孙节点
                for (ApiMetadataVO child : gatewayMetadata) {
                    if (child.getGroupId() == null || child.getGroupId() == 0L) {
                        //是父节点
                        OpenApiParameter.Schemas.SchemasBuilder schemas2 = OpenApiParameter.Schemas.builder().type("object").description(child.getDescription()).xml(OpenApiParameter.Xml.builder().name(child.getXmlName()).build());
                        int num = 0;
                        childDataByGateway(schemasMap, wgSchemasMap, child, schemas2, num);
                    }
                }
            }

            OpenApiParameter.Schemas.SchemasBuilder schemasRequestBody = OpenApiParameter.Schemas.builder().type("object").xml(OpenApiParameter.Xml.builder().name(api.getApiEname() + "Req").build());
            HashMap<String, OpenApiParameter.Schema> propertiesMap = new HashMap<>();
            List<String> reqList = new ArrayList<>();
            propertiesMap.put("requestData", OpenApiParameter.Schema.builder().ref("#/components/schemas/requestData").build());
            Iterator it = wgSchemasMap.keySet().iterator();
            while (it.hasNext()) {
                String key = (String) it.next();
                OpenApiParameter.Schemas schema = wgSchemasMap.get(key);
                if (schema != null) {
                    propertiesMap.put(key, OpenApiParameter.Schema.builder().xml(OpenApiParameter.Xml.builder().name(schema.getXml().getName()).build()).description(schema.getDescription()).type(schema.getType()).build());
                    schema.getRequired().forEach(s -> reqList.add(s));
                }
            }
            schemasRequestBody.properties(propertiesMap);
            schemasRequestBody.required(reqList);
            schemasMap.put(api.getApiEname() + "Req", schemasRequestBody.build());

            OpenApiParameter.Schemas.SchemasBuilder schemasResponseBody = OpenApiParameter.Schemas.builder().type("object").xml(OpenApiParameter.Xml.builder().name(api.getApiEname() + "Res").build());
            HashMap<String, OpenApiParameter.Schema> propertiesMap2 = new HashMap<>();
            propertiesMap2.put("responseData", OpenApiParameter.Schema.builder().ref("#/components/schemas/responseData").build());
            Iterator it2 = wgSchemasMap.keySet().iterator();
            List<String> resList = new ArrayList<>();
            while (it2.hasNext()) {
                String key = (String) it2.next();
                OpenApiParameter.Schemas schema = wgSchemasMap.get(key);
                if (schema != null) {
                    propertiesMap2.put(key, OpenApiParameter.Schema.builder().xml(OpenApiParameter.Xml.builder().name(schema.getXml().getName()).build()).description(schema.getDescription()).type(schema.getType()).build());
                    schema.getRequired().forEach(s -> resList.add(s));
                }
            }
            schemasResponseBody.properties(propertiesMap2);
            schemasResponseBody.required(resList);
            schemasMap.put(api.getApiEname() + "Res", schemasResponseBody.build());

            //json 对象构建
            OpenApiParameter.Components components = OpenApiParameter.Components.builder().schemas(schemasMap).build();
            openApi.components(components);

            //组装body 参数
            {
                ApiMetadata reqRef = apiMetadataService.findParentObjectByApiId(apiId);

                HashMap<String, OpenApiParameter.RequestBodySchema> schemaHashMap = new HashMap<>();
                if (reqRef != null) {
                    schemaHashMap.put("application/json", OpenApiParameter.RequestBodySchema.builder().schema(OpenApiParameter.Schema.builder().ref("#/components/schemas/" + reqRef.getName()).build()).build());
                    schemaHashMap.put("application/xml", OpenApiParameter.RequestBodySchema.builder().schema(OpenApiParameter.Schema.builder().ref("#/components/schemas/" + reqRef.getName()).build()).build());
                    OpenApiParameter.RequestBody requestBody = OpenApiParameter.RequestBody.builder().description(reqRef.getDescription()).content(schemaHashMap).required(true).build();
                    method.requestBody(requestBody);
                } else {
                    schemaHashMap.put("application/json", OpenApiParameter.RequestBodySchema.builder().schema(OpenApiParameter.Schema.builder().ref("#/components/schemas/" + api.getApiEname() + "Req").build()).build());
                    schemaHashMap.put("application/xml", OpenApiParameter.RequestBodySchema.builder().schema(OpenApiParameter.Schema.builder().ref("#/components/schemas/" + api.getApiEname() + "Req").build()).build());
                    OpenApiParameter.RequestBody requestBody = OpenApiParameter.RequestBody.builder().description("请求报文").content(schemaHashMap).required(true).build();
                    method.requestBody(requestBody);
                }

            }

            //组装响应参数
            {
                ApiMetadata respRef = apiMetadataService.findResObjectByApiId(apiId);
                HashMap<String, OpenApiParameter.RequestBodySchema> schemaHashMap = new HashMap<>();
                if (respRef != null) {
                    schemaHashMap.put("application/json", OpenApiParameter.RequestBodySchema.builder().schema(OpenApiParameter.Schema.builder().ref("#/components/schemas/" + respRef.getName()).build()).build());
                    schemaHashMap.put("application/xml", OpenApiParameter.RequestBodySchema.builder().schema(OpenApiParameter.Schema.builder().ref("#/components/schemas/" + respRef.getName()).build()).build());
                } else {
                    schemaHashMap.put("application/json", OpenApiParameter.RequestBodySchema.builder().schema(OpenApiParameter.Schema.builder().ref("#/components/schemas/" + api.getApiEname() + "Res").build()).build());
                    schemaHashMap.put("application/xml", OpenApiParameter.RequestBodySchema.builder().schema(OpenApiParameter.Schema.builder().ref("#/components/schemas/" + api.getApiEname() + "Res").build()).build());
                }


                HashMap<String, OpenApiParameter.Responses> mps = new HashMap<>();
                mps.put("200", OpenApiParameter.Responses.builder().description("返回成功").content(schemaHashMap).build());
                mps.put("500", OpenApiParameter.Responses.builder().description("返回成功").build());
                method.responses(mps);
            }

            // 路径信息组装
            {
                OpenApiParameter.Paths.PathsBuilder paths = OpenApiParameter.Paths.builder();
                if (api.getRequestMethod() == null) {
                    api.setRequestMethod(2);
                }
                //请求类型
                switch (api.getRequestMethod()) {
                    case 1:  //1: GET
                        paths.get(method.build());
                        break;
                    case 2://2: POST
                        paths.post(method.build());
                        break;
                    case 3://3: PUT
                        paths.put(method.build());
                        break;
                    case 4://4: DELETE
                        paths.delete(method.build());
                        break;
                    default:
                        paths.post(method.build());
                        break;
                }

                hashMap.put(api.getApiPath(), paths.build());
                openApi.paths(hashMap).build();
            }
        }

        //json 对象构建
        OpenApiParameter.Components components = OpenApiParameter.Components.builder().schemas(schemasMap).build();
        openApi.components(components);
        openApi.paths(hashMap).build();
        openApi.servers(new ArrayList<>(arrayList));


        String result = JSON.toJSONString(openApi.build()).replaceAll("ref", "\\$ref");
        log.info("result {}", result);

        return R.data(result);
    }


    /**
     * 前端传入json 转yml后的数据生成java sdk
     */
    @PostMapping("createProOpenApiYaml")
    @ApiOperationSupport(order = 9)
    @ApiOperation(value = "生成yaml文档、html文档和word文档", notes = "yamlMsg，APIId")
    @ApiLog("生成yaml文档、html文档和word文档")
    @Log(title = "生成yaml文档、html文档和word文档", businessType = BusinessType.OTHER)
    public R createProDOpenApiYaml(@RequestBody JSONObject json) {
        PrintStream ps = null;
        Long productId = json.getLong("productId");
        String proMsg = json.getString("proMsg");
        try {

            //创建product基本信息
            Product product = productService.getById(productId);
            if (product == null) {
                return R.fail(222, "该应用产品不存在");
            }

            String pathUrl = prodCodePath + product.getProductCode();

            File filePath = new File(pathUrl);
            if (!filePath.exists()) {
                if (!filePath.mkdirs()) {
                    return R.fail("文件创建失败!");
                }
            }
            File file = new File(pathUrl + "/proCode.yaml");
            ps = new PrintStream(new FileOutputStream(file));
            ps.println(proMsg);
            ps.flush();


            try {
//                String localPath = "";
//                if (!prodCodePath.endsWith("/")) {
//                    localPath = prodCodePath + "/";
//                } else {
//                    localPath = prodCodePath;
//                }
//                localPath = localPath + product.getProductEname();


//                R r = openapiGeneratorUtils.makeClient(pathUrl + "/proCode.yaml", localPath, "com.dhcc.openapi", product.getProductEname(), product.getProductVersion(), "", "", "");


                boolean bool = false;
                //根据应用产品查询关联api
                ProductApi productApi = new ProductApi();
                productApi.setProductId(productId);
                String sdkPath = prodCodePath + "/" + product.getProductEname() + "-client-sdk";
                List<ProductApi> productApiList = productApiService.listProductApi(productApi);
                for (int i = 0; i < productApiList.size(); i++) {
                    Long apiId = productApiList.get(i).getApiId();
                    R r = makeOpenApi(apiId);
                    com.dhcc.bpm.modules.api.entity.Api api = apiService.getById(apiId);
                    if(!SdkGenerateUtil.generateByContent(product.getProductEname(), api.getApiEname(), r.getData().toString(), sdkPath)){
                        return R.fail("JAVA SDK 生成失败");
                    }
                }

                if(isEnable){
                    if(!mavenInvokerUtils.createSdkJar(sdkPath + "/pom.xml")){
                        return R.fail("JAVA SDK 生成失败");
                    }
                    String oriPath = sdkPath + "/target/" + product.getProductEname() + "-client-1.0.0.jar";
                    String sdkJarPath = prodCodePath + "/sdkFile/" + product.getProductEname() + "-client-1.0.0.jar";
                    log.info("编译后jar包路径：[{}],sdk 存储路径：[{}]" , oriPath, sdkJarPath);
                    File oriSdkFile = new File(oriPath);
                    File tmpFile = new File(prodCodePath + "/sdkFile/");//获取文件夹路径
                    if (!tmpFile.exists()) {//判断文件夹是否创建，没有创建则创建新文件夹
                        tmpFile.mkdirs();
                    }
                    oriSdkFile.renameTo(new File(sdkJarPath));
                    //将生成的sdk文件源码进行压缩
                    ZipUtils.toZip(sdkJarPath, sdkPath + ".zip", true);
                }else{
                    //将生成的sdk文件源码进行压缩
                    ZipUtils.toZip(sdkPath, sdkPath + ".zip", true);
                }

                //压缩文件完成后删除源文件目录
                ZipUtils.delFiles(new File(sdkPath));

                //将sdk压缩文件上传到sdk管理表供门户下载使用
                Plupload plupload = null;
                QueryWrapper<Sdk> wrapper = new QueryWrapper<>();
                Sdk sdk = sdkService.getOne(wrapper.eq("sdk_name", product.getProductName())
                        .eq("sdk_version", product.getProductVersion()));
                if (sdk == null){
                    sdk = new Sdk();
                    // 设置SDK编号
                    String code = serialNumberService.generateSerialNumberByModelCode("opc_marketing");
                    sdk.setSdkCode(code);
                    sdk.setSdkName(product.getProductName());
                    sdk.setSdkVersion(product.getProductVersion());
                    sdk.setType(1);
                    sdk.setOpcProductId(product.getId());
                    sdk.setStatus(2);
                    sdk.setIsDeleted(0);
                }
                sdk.setKeyValue(1);
                if(sdk.getOpcPluploadId() != null && !"".equals(sdk.getOpcPluploadId())){
                    plupload = pluploadService.getById(sdk.getOpcPluploadId());
                }
                if(plupload == null){
                    plupload = new Plupload();
                }

                plupload.setOriginalPath(sdkPath + ".zip");
                plupload.setStorageName(product.getProductEname() + "-client-sdk.zip");
                plupload.setFileFullpath(sdkPath + ".zip");
                plupload.setFileRealname(product.getProductEname() + "-client-sdk.zip");
                plupload.setStorageType(Long.parseLong("1"));
                pluploadService.saveOrUpdate(plupload);
                sdk.setOpcPluploadId(plupload.getId());
                bool = sdkService.saveOrUpdate(sdk);
                if (!bool) {
                    return R.fail("JAVA SDK 生成失败");
                } else {
                    log.info("JAVA SDK 生成成功");
                    return R.success("JAVA SDK 生成成功");
                }

            } catch (Exception e) {
                log.error("JAVA HTML 文档生成失败:{}", e);
                return R.fail("JAVA HTML 文档生成失败");
            }


        } catch (Exception e) {
            log.error("写入数据失败:{}", e);
            return R.fail("生成JAVA 客户端代码失败:" + e.getMessage());
        } finally {
            if (ps != null) {
                ps.close();
            }

        }
    }

    /**
     * @author: zhangzexu
     * @date: 2020/08/19 10:35
     * @description: log文件下载
     * @param: [filePath, response]
     * @return: org.springblade.core.tool.api.R
     */
    @ApiLog("java sdk下载")
    @GetMapping("/sdkDownload")
    @Log(title = "产品的sdk下载", businessType = BusinessType.DOWNLOAD)
    public R downloadFile(@RequestParam Long productId, HttpServletResponse response) {

        //创建product基本信息
        Product product = productService.getById(productId);
        if (product == null) {
            return R.fail(222, "该应用产品不存在");
        }
        String pathUrl = path + "/product/" + product.getProductCode();

        File file = new File(pathUrl + "/" + product.getProductEname() + "-" + product.getProductVersion() + ".jar");
        if (!file.exists()) {
            return R.fail("文件不存在,请先前往API管理 > 应用产品 > 点击生成SDK 进行生成后再进行下载SDK");
        }
        if (com.dhcc.bpm.common.utils.FileUtils.downloadFile(pathUrl + "/" + product.getProductEname() + "-" + product.getProductVersion() + ".jar", response)) {
            return R.status(true);
        } else {
            return R.fail("文件不存在");
        }

    }


    /**
     * @author: zhangzexu
     * @date: 2020/08/19 10:35
     * @description: log文件下载
     * @param: [filePath, response]
     * @return: org.springblade.core.tool.api.R
     */
    @ApiLog("html2 sdk使用文档下载")
    @GetMapping("/html2Download")
    @Log(title = "html2 sdk使用文档下载", businessType = BusinessType.DOWNLOAD)
    public R html2Download(@RequestParam Long productId, @RequestParam String name, HttpServletResponse response) {
        //创建product基本信息
        Product product = productService.getById(productId);
        if (product == null) {
            return R.fail(222, "该应用产品不存在");
        }
        String pathUrl = path + "/product/" + product.getProductCode();

        File file = new File(pathUrl + "/" + name);
        if (!file.exists()) {
            return R.fail("文件不存在,请先前往API管理 > 应用产品 > 点击生成SDK 进行生成后再进行下载SDK使用文档");
        }
        if (com.dhcc.bpm.common.utils.FileUtils.htmlBrowse(pathUrl + "/" + name, response)) {
            return R.status(true);
        } else {
            return R.fail("文件不存在");
        }

    }


    /**
     * 上传文件到服务器
     *
     * @Author wangjinghan
     * @date: 2020/8/7 9:09
     */
    @PostMapping("/up")
    public Long upLoadServer(String pathUrl, String fileName) throws IOException {
//        pathUrl="/idata/file/openapi/A0159";
//        fileName="apiCode.doc";
        Plupload plupload = new Plupload();
        plupload.setFileRealname(fileName);
        plupload.setFileFullpath(pathUrl + "/" + fileName);
        plupload.setStorageName(fileName);
        Param param = paramService.getParamByKey("bpm.docLocalUpload");
        String paramValue = param.getParamValue();
        plupload.setStorageType(Long.valueOf(paramValue));
        Upload upload = new Upload();
        upload.setName(fileName);
        File pdf = new File(pathUrl + "/" + fileName);

        FileInputStream fileInputStream = null;
        fileInputStream = new FileInputStream(pdf);

        MultipartFile multipartFile = new MockMultipartFile(pdf.getName(), pdf.getName(),
                ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStream);
        upload.setMultipartFile(multipartFile);
        Long id = pluploadService.fileUploadS(plupload, upload);
        return id;
    }


    @PostMapping("downloadOpenApi")
    @ApiOperationSupport(order = 10)
    @ApiOperation(value = "文档下载", notes = "apiId，name")
    @ApiLog("文档下载")
    @Log(title = "文档下载", businessType = BusinessType.EXPORT)
    public Resource downloadOpenApi(@Valid String apiId, String name, HttpServletResponse response) {
        //配置文件中加个字段来控制本地下载还是文件服务器下载,实现切换
        Resource resource = null;
        if ("1".equals(isNative)) {
            try {
                com.dhcc.bpm.modules.api.entity.Api api = apiService.getById(apiId);
                String pathUrl = path + "/" + api.getApiCode();
                name = com.dhcc.bpm.common.utils.StringUtils.downLoadReplace(name);
                resource = new UrlResource(new File(pathUrl + "/" + name).toURI());
            } catch (MalformedURLException e) {
                log.error("文档下载异常：{}", e);
            }
            return resource;
        } else {
            //服务器下载
            com.dhcc.bpm.modules.api.entity.Api api = apiService.getById(apiId);
            String[] files = api.getFileIds().split(",");
            for (String id : files) {
                pluploadService.fileDownloadServer(Long.valueOf(id), response);
            }
            return resource;
        }

    }


    final static Base64.Encoder encoder = Base64.getEncoder();
    final static Base64.Decoder decoder = Base64.getDecoder();

    /**
     * 给字符串加密
     *
     * @param text
     * @return
     */
    public static String encode(String text) {
        return encoder.encodeToString(text.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 将加密后的字符串进行解密
     *
     * @param encodedText
     * @return
     */
    public static String decode(String encodedText) {
        return new String(decoder.decode(encodedText), StandardCharsets.UTF_8);
    }


    public HashMap<String, OpenApiParameter.Schemas> childData(HashMap<String, OpenApiParameter.Schemas> schemasMap, ApiMetadataVO apiMetadataVO, OpenApiParameter.Schemas.SchemasBuilder schemas) {

        //添加必填参数校验
        List<String> required = new ArrayList<>();

        HashMap<String, OpenApiParameter.Schema> propertiesMap = new HashMap<>();
        List<ApiMetadataVO> childern = apiMetadataService.findChildByGroupId(apiMetadataVO.getId());

        for (ApiMetadataVO child : childern) {
            log.info("node ApiMetadata:{}", child);

            if ("2".equals(child.getElementType())) {
                return childData(schemasMap, child, schemas);
            }

            if ("object".equals(child.getType())) {
                propertiesMap.put(child.getName(), OpenApiParameter.Schema.builder().ref("#/components/schemas/" + child.getName() + child.getBodyType()).build());
            } else if ("enum".equals(child.getType())) {
                propertiesMap.put(child.getName(), OpenApiParameter.Schema.builder().type(child.getTypeFormat()).description(child.getDescription()).xml(OpenApiParameter.Xml.builder().name(child.getName()).wrapped(Boolean.valueOf(child.getXmlWrapped())).build()).Enum(Arrays.asList(333, 44)).build());
                if (Boolean.valueOf(child.getIsRequired())) {
                    required.add(child.getName());
                }
            } else if ("array".equals(child.getType()) || "list".equals(child.getType())) {
                OpenApiParameter.Items.ItemsBuilder itemsBuilder = OpenApiParameter.Items.builder();
                if ("object".equals(child.getTypeFormat())) {
                    //查出这个对应的组
                    itemsBuilder.ref("#/components/schemas/");
                } else {
                    itemsBuilder.type(child.getTypeFormat());
                }
                propertiesMap.put(child.getName(), OpenApiParameter.Schema.builder().type("array").description(child.getDescription()).xml(OpenApiParameter.Xml.builder().name(child.getName()).wrapped(Boolean.valueOf(child.getXmlWrapped())).build()).items(itemsBuilder.build()).build());
                if (!"object".equals(child.getTypeFormat())) {
                    if (Boolean.valueOf(child.getIsRequired())) {
                        required.add(child.getName());
                    }
                }
            } else {
                propertiesMap.put(child.getName(), OpenApiParameter.Schema.builder().type(child.getType()).description(child.getDescription()).format(child.getTypeFormat()).xml(OpenApiParameter.Xml.builder().name(child.getName()).wrapped(Boolean.valueOf(child.getXmlWrapped())).build()).build());
                if (Boolean.valueOf(child.getIsRequired())) {
                    required.add(child.getName());
                }
            }

        }

        if (!required.isEmpty()) {
            schemas.required(required);
        }
        schemas.properties(propertiesMap);
        schemasMap.put(apiMetadataVO.getName() + apiMetadataVO.getBodyType(), schemas.build());

        return schemasMap;
    }


    public HashMap<String, OpenApiParameter.Schemas> childDataByGateway(HashMap<String, OpenApiParameter.Schemas> schemasMap,
                                                                        HashMap<String, OpenApiParameter.Schemas> wgSchemasMap,
                                                                        ApiMetadataVO apiMetadataVO, OpenApiParameter.Schemas.SchemasBuilder schemas, int num) {

        //添加必填参数校验
        List<String> required = new ArrayList<>();

        HashMap<String, OpenApiParameter.Schema> propertiesMap = new HashMap<>();
        List<ApiMetadataVO> childern = apiMetadataService.findChildByGroupId(apiMetadataVO.getId());

        if (num == 0 && childern.size() == 0) {
            schemas = OpenApiParameter.Schemas.builder().type(apiMetadataVO.getType()).xml(OpenApiParameter.Xml.builder().name(apiMetadataVO.getXmlName()).build()).description(apiMetadataVO.getDescription());
            if ("true".equals(apiMetadataVO.getIsRequired())) {
                required.add(apiMetadataVO.getName());
            }
        }
        for (ApiMetadataVO child : childern) {
            log.info("node ApiMetadata:{}", child);

            if ("2".equals(child.getElementType())) {
                return childDataByGateway(schemasMap, wgSchemasMap, child, schemas, ++num);
            }

            if ("object".equals(child.getType())) {
                propertiesMap.put(child.getName(), OpenApiParameter.Schema.builder().ref("#/components/schemas/" + child.getName() + child.getBodyType()).build());
            } else if ("enum".equals(child.getType())) {
                propertiesMap.put(child.getName(), OpenApiParameter.Schema.builder().type(child.getTypeFormat()).description(child.getDescription()).xml(OpenApiParameter.Xml.builder().name(child.getName()).wrapped(Boolean.valueOf(child.getXmlWrapped())).build()).Enum(Arrays.asList(333, 44)).build());
                if (Boolean.valueOf(child.getIsRequired())) {
                    required.add(child.getName());
                }
            } else if ("array".equals(child.getType()) || "list".equals(child.getType())) {
                OpenApiParameter.Items.ItemsBuilder itemsBuilder = OpenApiParameter.Items.builder();
                if ("object".equals(child.getTypeFormat())) {
                    //查出这个对应的组
                    itemsBuilder.ref("#/components/schemas/");
                } else {
                    itemsBuilder.type(child.getTypeFormat());
                }
                propertiesMap.put(child.getName(), OpenApiParameter.Schema.builder().type("array").description(child.getDescription()).xml(OpenApiParameter.Xml.builder().name(child.getName()).wrapped(Boolean.valueOf(child.getXmlWrapped())).build()).items(itemsBuilder.build()).build());
                if (!"object".equals(child.getTypeFormat())) {
                    if (Boolean.valueOf(child.getIsRequired())) {
                        required.add(child.getName());
                    }
                }
            } else {
                propertiesMap.put(child.getName(), OpenApiParameter.Schema.builder().type(child.getType()).description(child.getDescription()).format(child.getTypeFormat()).xml(OpenApiParameter.Xml.builder().name(child.getName()).wrapped(Boolean.valueOf(child.getXmlWrapped())).build()).build());
                if (Boolean.valueOf(child.getIsRequired())) {
                    required.add(child.getName());
                }
            }

        }

        if (!required.isEmpty()) {
            schemas.required(required);
        }
        schemas.properties(propertiesMap);
//        schemasMap.put(apiMetadataVO.getName(), schemas.build());
        wgSchemasMap.put(apiMetadataVO.getName(), schemas.build());

        return schemasMap;
    }
}
